blob: 0e51ba3ba379c9e7d5bfd539a56e791972dce978 [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"
Anton Korobeynikov55bcea12010-01-10 12:58:08 +000015#include "TargetAttributesSema.h"
Chris Lattner2c6fcf52008-06-26 18:38:35 +000016#include "clang/AST/ASTContext.h"
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +000017#include "clang/AST/CXXInheritance.h"
John McCall28a0cf72010-08-25 07:42:41 +000018#include "clang/AST/DeclCXX.h"
Daniel Dunbar56fdb6a2008-08-11 06:23:49 +000019#include "clang/AST/DeclObjC.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000020#include "clang/AST/DeclTemplate.h"
Daniel Dunbar56fdb6a2008-08-11 06:23:49 +000021#include "clang/AST/Expr.h"
John McCall31168b02011-06-15 23:02:42 +000022#include "clang/Basic/SourceManager.h"
Chris Lattneracbc2d22008-06-27 22:18:37 +000023#include "clang/Basic/TargetInfo.h"
John McCall8b0666c2010-08-20 18:27:03 +000024#include "clang/Sema/DeclSpec.h"
John McCallb45a1e72010-08-26 02:13:20 +000025#include "clang/Sema/DelayedDiagnostic.h"
John McCallf1e8b342011-09-29 07:17:38 +000026#include "clang/Sema/Lookup.h"
Richard Smithe233fbf2013-01-28 22:42:45 +000027#include "clang/Sema/Scope.h"
Chris Lattner30ba6742009-08-10 19:03:04 +000028#include "llvm/ADT/StringExtras.h"
Chris Lattner2c6fcf52008-06-26 18:38:35 +000029using namespace clang;
John McCallb45a1e72010-08-26 02:13:20 +000030using namespace sema;
Chris Lattner2c6fcf52008-06-26 18:38:35 +000031
John McCall5fca7ea2011-03-02 12:29:23 +000032/// These constants match the enumerated choices of
33/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +000034enum AttributeDeclKind {
John McCall5fca7ea2011-03-02 12:29:23 +000035 ExpectedFunction,
36 ExpectedUnion,
37 ExpectedVariableOrFunction,
38 ExpectedFunctionOrMethod,
39 ExpectedParameter,
John McCall5fca7ea2011-03-02 12:29:23 +000040 ExpectedFunctionMethodOrBlock,
Kaelyn Uhrain8681f9d2012-11-12 23:48:05 +000041 ExpectedFunctionMethodOrClass,
John McCall5fca7ea2011-03-02 12:29:23 +000042 ExpectedFunctionMethodOrParameter,
43 ExpectedClass,
John McCall5fca7ea2011-03-02 12:29:23 +000044 ExpectedVariable,
45 ExpectedMethod,
Caitlin Sadowski63fa6672011-07-28 20:12:35 +000046 ExpectedVariableFunctionOrLabel,
Douglas Gregor5c3cc422012-03-14 16:55:17 +000047 ExpectedFieldOrGlobalVar,
Hans Wennborgd3b01bc2012-06-23 11:51:46 +000048 ExpectedStruct,
Kaelyn Uhrain8681f9d2012-11-12 23:48:05 +000049 ExpectedVariableFunctionOrTag,
Hans Wennborgd3b01bc2012-06-23 11:51:46 +000050 ExpectedTLSVar
John McCall5fca7ea2011-03-02 12:29:23 +000051};
52
Chris Lattner58418ff2008-06-29 00:16:31 +000053//===----------------------------------------------------------------------===//
54// Helper functions
55//===----------------------------------------------------------------------===//
56
Chandler Carruthff4c4f02011-07-01 23:49:12 +000057static const FunctionType *getFunctionType(const Decl *D,
Ted Kremenek527042b2009-08-14 20:49:40 +000058 bool blocksToo = true) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +000059 QualType Ty;
Chandler Carruthff4c4f02011-07-01 23:49:12 +000060 if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
Chris Lattner2c6fcf52008-06-26 18:38:35 +000061 Ty = decl->getType();
Chandler Carruthff4c4f02011-07-01 23:49:12 +000062 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
Chris Lattner2c6fcf52008-06-26 18:38:35 +000063 Ty = decl->getType();
Chandler Carruthff4c4f02011-07-01 23:49:12 +000064 else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
Chris Lattner2c6fcf52008-06-26 18:38:35 +000065 Ty = decl->getUnderlyingType();
66 else
67 return 0;
Mike Stumpd3bb5572009-07-24 19:02:52 +000068
Chris Lattner2c6fcf52008-06-26 18:38:35 +000069 if (Ty->isFunctionPointerType())
Ted Kremenekc23c7e62009-07-29 21:53:49 +000070 Ty = Ty->getAs<PointerType>()->getPointeeType();
Fariborz Jahanian28c433d2009-05-18 17:39:25 +000071 else if (blocksToo && Ty->isBlockPointerType())
Ted Kremenekc23c7e62009-07-29 21:53:49 +000072 Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
Daniel Dunbar70e3eba2008-10-19 02:04:16 +000073
John McCall9dd450b2009-09-21 23:43:11 +000074 return Ty->getAs<FunctionType>();
Chris Lattner2c6fcf52008-06-26 18:38:35 +000075}
76
Daniel Dunbarc136e0c2008-09-26 04:12:28 +000077// FIXME: We should provide an abstraction around a method or function
78// to provide the following bits of information.
79
Nuno Lopes518e3702009-12-20 23:11:08 +000080/// isFunction - Return true if the given decl has function
Ted Kremenek527042b2009-08-14 20:49:40 +000081/// type (function or function-typed variable).
Chandler Carruthff4c4f02011-07-01 23:49:12 +000082static bool isFunction(const Decl *D) {
83 return getFunctionType(D, false) != NULL;
Ted Kremenek527042b2009-08-14 20:49:40 +000084}
85
86/// isFunctionOrMethod - Return true if the given decl has function
Daniel Dunbar70e3eba2008-10-19 02:04:16 +000087/// type (function or function-typed variable) or an Objective-C
88/// method.
Chandler Carruthff4c4f02011-07-01 23:49:12 +000089static bool isFunctionOrMethod(const Decl *D) {
Nick Lewyckyb9e4a3a2012-07-24 01:31:55 +000090 return isFunction(D) || isa<ObjCMethodDecl>(D);
Daniel Dunbarc136e0c2008-09-26 04:12:28 +000091}
92
Fariborz Jahanian4447e172009-05-15 23:15:03 +000093/// isFunctionOrMethodOrBlock - Return true if the given decl has function
94/// type (function or function-typed variable) or an Objective-C
95/// method or a block.
Chandler Carruthff4c4f02011-07-01 23:49:12 +000096static bool isFunctionOrMethodOrBlock(const Decl *D) {
97 if (isFunctionOrMethod(D))
Fariborz Jahanian4447e172009-05-15 23:15:03 +000098 return true;
99 // check for block is more involved.
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000100 if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
Fariborz Jahanian4447e172009-05-15 23:15:03 +0000101 QualType Ty = V->getType();
102 return Ty->isBlockPointerType();
103 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000104 return isa<BlockDecl>(D);
Fariborz Jahanian4447e172009-05-15 23:15:03 +0000105}
106
John McCall3882ace2011-01-05 12:14:39 +0000107/// Return true if the given decl has a declarator that should have
108/// been processed by Sema::GetTypeForDeclarator.
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000109static bool hasDeclarator(const Decl *D) {
John McCall31168b02011-06-15 23:02:42 +0000110 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000111 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
112 isa<ObjCPropertyDecl>(D);
John McCall3882ace2011-01-05 12:14:39 +0000113}
114
Daniel Dunbar70e3eba2008-10-19 02:04:16 +0000115/// hasFunctionProto - Return true if the given decl has a argument
116/// information. This decl should have already passed
Fariborz Jahanian4447e172009-05-15 23:15:03 +0000117/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000118static bool hasFunctionProto(const Decl *D) {
119 if (const FunctionType *FnTy = getFunctionType(D))
Douglas Gregordeaad8c2009-02-26 23:50:07 +0000120 return isa<FunctionProtoType>(FnTy);
Fariborz Jahanian4447e172009-05-15 23:15:03 +0000121 else {
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000122 assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
Daniel Dunbar70e3eba2008-10-19 02:04:16 +0000123 return true;
124 }
125}
126
127/// getFunctionOrMethodNumArgs - Return number of function or method
128/// arguments. It is an error to call this on a K&R function (use
129/// hasFunctionProto first).
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000130static unsigned getFunctionOrMethodNumArgs(const Decl *D) {
131 if (const FunctionType *FnTy = getFunctionType(D))
Douglas Gregordeaad8c2009-02-26 23:50:07 +0000132 return cast<FunctionProtoType>(FnTy)->getNumArgs();
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000133 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
Fariborz Jahanian960910a2009-05-19 17:08:59 +0000134 return BD->getNumParams();
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000135 return cast<ObjCMethodDecl>(D)->param_size();
Daniel Dunbarc136e0c2008-09-26 04:12:28 +0000136}
137
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000138static QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
139 if (const FunctionType *FnTy = getFunctionType(D))
Douglas Gregordeaad8c2009-02-26 23:50:07 +0000140 return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000141 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
Fariborz Jahanian960910a2009-05-19 17:08:59 +0000142 return BD->getParamDecl(Idx)->getType();
Mike Stumpd3bb5572009-07-24 19:02:52 +0000143
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000144 return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
Daniel Dunbarc136e0c2008-09-26 04:12:28 +0000145}
146
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000147static QualType getFunctionOrMethodResultType(const Decl *D) {
148 if (const FunctionType *FnTy = getFunctionType(D))
Fariborz Jahanianf1c25022009-05-20 17:41:43 +0000149 return cast<FunctionProtoType>(FnTy)->getResultType();
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000150 return cast<ObjCMethodDecl>(D)->getResultType();
Fariborz Jahanianf1c25022009-05-20 17:41:43 +0000151}
152
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000153static bool isFunctionOrMethodVariadic(const Decl *D) {
154 if (const FunctionType *FnTy = getFunctionType(D)) {
Douglas Gregordeaad8c2009-02-26 23:50:07 +0000155 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
Daniel Dunbarc136e0c2008-09-26 04:12:28 +0000156 return proto->isVariadic();
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000157 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
Ted Kremenek8af4f402010-04-29 16:48:58 +0000158 return BD->isVariadic();
Fariborz Jahanian960910a2009-05-19 17:08:59 +0000159 else {
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000160 return cast<ObjCMethodDecl>(D)->isVariadic();
Daniel Dunbarc136e0c2008-09-26 04:12:28 +0000161 }
162}
163
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000164static bool isInstanceMethod(const Decl *D) {
165 if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
Chandler Carruth743682b2010-11-16 08:35:43 +0000166 return MethodDecl->isInstance();
167 return false;
168}
169
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000170static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
John McCall9dd450b2009-09-21 23:43:11 +0000171 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
Chris Lattner574dee62008-07-26 22:17:49 +0000172 if (!PT)
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000173 return false;
Mike Stumpd3bb5572009-07-24 19:02:52 +0000174
John McCall96fa4842010-05-17 21:00:27 +0000175 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
176 if (!Cls)
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000177 return false;
Mike Stumpd3bb5572009-07-24 19:02:52 +0000178
John McCall96fa4842010-05-17 21:00:27 +0000179 IdentifierInfo* ClsName = Cls->getIdentifier();
Mike Stumpd3bb5572009-07-24 19:02:52 +0000180
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000181 // FIXME: Should we walk the chain of classes?
182 return ClsName == &Ctx.Idents.get("NSString") ||
183 ClsName == &Ctx.Idents.get("NSMutableString");
184}
185
Daniel Dunbar980c6692008-09-26 03:32:58 +0000186static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000187 const PointerType *PT = T->getAs<PointerType>();
Daniel Dunbar980c6692008-09-26 03:32:58 +0000188 if (!PT)
189 return false;
190
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000191 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
Daniel Dunbar980c6692008-09-26 03:32:58 +0000192 if (!RT)
193 return false;
Mike Stumpd3bb5572009-07-24 19:02:52 +0000194
Daniel Dunbar980c6692008-09-26 03:32:58 +0000195 const RecordDecl *RD = RT->getDecl();
Abramo Bagnara6150c882010-05-11 21:36:43 +0000196 if (RD->getTagKind() != TTK_Struct)
Daniel Dunbar980c6692008-09-26 03:32:58 +0000197 return false;
198
199 return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
200}
201
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000202/// \brief Check if the attribute has exactly as many args as Num. May
203/// output an error.
Chandler Carruthfcc48d92011-07-11 23:30:35 +0000204static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
205 unsigned int Num) {
206 if (Attr.getNumArgs() != Num) {
207 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
208 return false;
209 }
210
211 return true;
212}
213
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000214
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000215/// \brief Check if the attribute has at least as many args as Num. May
216/// output an error.
217static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
218 unsigned int Num) {
219 if (Attr.getNumArgs() < Num) {
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000220 S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
221 return false;
222 }
223
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000224 return true;
225}
226
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +0000227/// \brief Check if IdxExpr is a valid argument index for a function or
228/// instance method D. May output an error.
229///
230/// \returns true if IdxExpr is a valid index.
231static bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D,
232 StringRef AttrName,
233 SourceLocation AttrLoc,
234 unsigned AttrArgNum,
235 const Expr *IdxExpr,
236 uint64_t &Idx)
237{
238 assert(isFunctionOrMethod(D) && hasFunctionProto(D));
239
240 // In C++ the implicit 'this' function parameter also counts.
241 // Parameters are counted from one.
242 const bool HasImplicitThisParam = isInstanceMethod(D);
243 const unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
244 const unsigned FirstIdx = 1;
245
246 llvm::APSInt IdxInt;
247 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
248 !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) {
249 S.Diag(AttrLoc, diag::err_attribute_argument_n_not_int)
250 << AttrName << AttrArgNum << IdxExpr->getSourceRange();
251 return false;
252 }
253
254 Idx = IdxInt.getLimitedValue();
255 if (Idx < FirstIdx || (!isFunctionOrMethodVariadic(D) && Idx > NumArgs)) {
256 S.Diag(AttrLoc, diag::err_attribute_argument_out_of_bounds)
257 << AttrName << AttrArgNum << IdxExpr->getSourceRange();
258 return false;
259 }
260 Idx--; // Convert to zero-based.
261 if (HasImplicitThisParam) {
262 if (Idx == 0) {
263 S.Diag(AttrLoc,
264 diag::err_attribute_invalid_implicit_this_argument)
265 << AttrName << IdxExpr->getSourceRange();
266 return false;
267 }
268 --Idx;
269 }
270
271 return true;
272}
273
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000274///
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000275/// \brief Check if passed in Decl is a field or potentially shared global var
276/// \return true if the Decl is a field or potentially shared global variable
277///
Benjamin Kramer3c05b7c2011-08-02 04:50:49 +0000278static bool mayBeSharedVariable(const Decl *D) {
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000279 if (isa<FieldDecl>(D))
280 return true;
Benjamin Kramer3c05b7c2011-08-02 04:50:49 +0000281 if (const VarDecl *vd = dyn_cast<VarDecl>(D))
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000282 return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
283
284 return false;
285}
286
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000287/// \brief Check if the passed-in expression is of type int or bool.
288static bool isIntOrBool(Expr *Exp) {
289 QualType QT = Exp->getType();
290 return QT->isBooleanType() || QT->isIntegerType();
291}
292
DeLesley Hutchinse09be232012-04-23 18:39:55 +0000293
294// Check to see if the type is a smart pointer of some kind. We assume
295// it's a smart pointer if it defines both operator-> and operator*.
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000296static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
297 DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
298 S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
David Blaikieff7d47a2012-12-19 00:45:41 +0000299 if (Res1.empty())
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000300 return false;
DeLesley Hutchinse09be232012-04-23 18:39:55 +0000301
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000302 DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
303 S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
David Blaikieff7d47a2012-12-19 00:45:41 +0000304 if (Res2.empty())
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000305 return false;
306
307 return true;
DeLesley Hutchinse09be232012-04-23 18:39:55 +0000308}
309
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000310/// \brief Check if passed in Decl is a pointer type.
311/// Note that this function may produce an error message.
312/// \return true if the Decl is a pointer type; false otherwise
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000313static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
314 const AttributeList &Attr) {
Benjamin Kramer3c05b7c2011-08-02 04:50:49 +0000315 if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000316 QualType QT = vd->getType();
Benjamin Kramer3c05b7c2011-08-02 04:50:49 +0000317 if (QT->isAnyPointerType())
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000318 return true;
DeLesley Hutchinse09be232012-04-23 18:39:55 +0000319
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000320 if (const RecordType *RT = QT->getAs<RecordType>()) {
321 // If it's an incomplete type, it could be a smart pointer; skip it.
322 // (We don't want to force template instantiation if we can avoid it,
323 // since that would alter the order in which templates are instantiated.)
324 if (RT->isIncompleteType())
325 return true;
326
327 if (threadSafetyCheckIsSmartPointer(S, RT))
328 return true;
329 }
DeLesley Hutchinse09be232012-04-23 18:39:55 +0000330
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000331 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000332 << Attr.getName()->getName() << QT;
333 } else {
334 S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
335 << Attr.getName();
336 }
337 return false;
338}
339
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000340/// \brief Checks that the passed in QualType either is of RecordType or points
341/// to RecordType. Returns the relevant RecordType, null if it does not exit.
Benjamin Kramer56b675f2011-08-19 04:18:11 +0000342static const RecordType *getRecordType(QualType QT) {
343 if (const RecordType *RT = QT->getAs<RecordType>())
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000344 return RT;
Benjamin Kramer56b675f2011-08-19 04:18:11 +0000345
346 // Now check if we point to record type.
347 if (const PointerType *PT = QT->getAs<PointerType>())
348 return PT->getPointeeType()->getAs<RecordType>();
349
350 return 0;
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000351}
352
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +0000353
Jordy Rose740b0c22012-05-08 03:27:22 +0000354static bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier,
355 CXXBasePath &Path, void *Unused) {
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +0000356 const RecordType *RT = Specifier->getType()->getAs<RecordType>();
357 if (RT->getDecl()->getAttr<LockableAttr>())
358 return true;
359 return false;
360}
361
362
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000363/// \brief Thread Safety Analysis: Checks that the passed in RecordType
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000364/// resolves to a lockable object.
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000365static void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
366 QualType Ty) {
367 const RecordType *RT = getRecordType(Ty);
Michael Hana9171bc2012-08-03 17:40:43 +0000368
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000369 // Warn if could not get record type for this argument.
Benjamin Kramer2667afa2011-09-03 03:30:59 +0000370 if (!RT) {
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000371 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000372 << Attr.getName() << Ty.getAsString();
373 return;
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000374 }
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000375
Michael Hana9171bc2012-08-03 17:40:43 +0000376 // Don't check for lockable if the class hasn't been defined yet.
DeLesley Hutchins3509f292012-02-16 17:15:51 +0000377 if (RT->isIncompleteType())
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000378 return;
DeLesley Hutchins90ff4682012-05-02 22:18:42 +0000379
380 // Allow smart pointers to be used as lockable objects.
381 // FIXME -- Check the type that the smart pointer points to.
382 if (threadSafetyCheckIsSmartPointer(S, RT))
383 return;
384
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +0000385 // Check if the type is lockable.
386 RecordDecl *RD = RT->getDecl();
387 if (RD->getAttr<LockableAttr>())
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000388 return;
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +0000389
390 // Else check if any base classes are lockable.
391 if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
392 CXXBasePaths BPaths(false, false);
393 if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths))
394 return;
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000395 }
DeLesley Hutchins5ff430c2012-05-04 16:28:38 +0000396
397 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
398 << Attr.getName() << Ty.getAsString();
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000399}
400
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000401/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000402/// from Sidx, resolve to a lockable object.
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000403/// \param Sidx The attribute argument index to start checking with.
404/// \param ParamIdxOk Whether an argument can be indexing into a function
405/// parameter list.
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000406static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000407 const AttributeList &Attr,
408 SmallVectorImpl<Expr*> &Args,
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000409 int Sidx = 0,
410 bool ParamIdxOk = false) {
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000411 for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000412 Expr *ArgExp = Attr.getArg(Idx);
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000413
Caitlin Sadowski990d5712011-09-08 17:42:31 +0000414 if (ArgExp->isTypeDependent()) {
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000415 // FIXME -- need to check this again on template instantiation
Caitlin Sadowski990d5712011-09-08 17:42:31 +0000416 Args.push_back(ArgExp);
417 continue;
418 }
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000419
DeLesley Hutchins70b5e8e2012-04-23 16:45:01 +0000420 if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
DeLesley Hutchinsa5a00e82012-09-07 17:34:53 +0000421 if (StrLit->getLength() == 0 ||
422 StrLit->getString() == StringRef("*")) {
DeLesley Hutchins3c3d57b2012-08-31 21:57:32 +0000423 // Pass empty strings to the analyzer without warnings.
DeLesley Hutchinsa5a00e82012-09-07 17:34:53 +0000424 // Treat "*" as the universal lock.
DeLesley Hutchins3c3d57b2012-08-31 21:57:32 +0000425 Args.push_back(ArgExp);
DeLesley Hutchins70b5e8e2012-04-23 16:45:01 +0000426 continue;
DeLesley Hutchins3c3d57b2012-08-31 21:57:32 +0000427 }
DeLesley Hutchins70b5e8e2012-04-23 16:45:01 +0000428
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000429 // We allow constant strings to be used as a placeholder for expressions
430 // that are not valid C++ syntax, but warn that they are ignored.
431 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
432 Attr.getName();
DeLesley Hutchins3c3d57b2012-08-31 21:57:32 +0000433 Args.push_back(ArgExp);
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000434 continue;
435 }
436
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000437 QualType ArgTy = ArgExp->getType();
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000438
DeLesley Hutchins70b5e8e2012-04-23 16:45:01 +0000439 // A pointer to member expression of the form &MyClass::mu is treated
440 // specially -- we need to look at the type of the member.
441 if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
442 if (UOp->getOpcode() == UO_AddrOf)
443 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
444 if (DRE->getDecl()->isCXXInstanceMember())
445 ArgTy = DRE->getDecl()->getType();
446
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000447 // First see if we can just cast to record type, or point to record type.
448 const RecordType *RT = getRecordType(ArgTy);
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000449
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000450 // Now check if we index into a record type function param.
451 if(!RT && ParamIdxOk) {
452 FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000453 IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
454 if(FD && IL) {
455 unsigned int NumParams = FD->getNumParams();
456 llvm::APInt ArgValue = IL->getValue();
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000457 uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
458 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
459 if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000460 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
461 << Attr.getName() << Idx + 1 << NumParams;
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000462 continue;
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000463 }
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000464 ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000465 }
466 }
467
DeLesley Hutchins481d5ab2012-04-06 20:02:30 +0000468 checkForLockableRecord(S, D, Attr, ArgTy);
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000469
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000470 Args.push_back(ArgExp);
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000471 }
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000472}
473
Chris Lattner58418ff2008-06-29 00:16:31 +0000474//===----------------------------------------------------------------------===//
Chris Lattner58418ff2008-06-29 00:16:31 +0000475// Attribute Implementations
476//===----------------------------------------------------------------------===//
477
Daniel Dunbar032db472008-07-31 22:40:48 +0000478// FIXME: All this manual attribute parsing code is gross. At the
479// least add some helper functions to check most argument patterns (#
480// and types of args).
481
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000482enum ThreadAttributeDeclKind {
483 ThreadExpectedFieldOrGlobalVar,
484 ThreadExpectedFunctionOrMethod,
485 ThreadExpectedClassOrStruct
486};
487
Michael Hana9171bc2012-08-03 17:40:43 +0000488static bool checkGuardedVarAttrCommon(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000489 const AttributeList &Attr) {
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000490 assert(!Attr.isInvalid());
491
492 if (!checkAttributeNumArgs(S, Attr, 0))
Michael Han3be3b442012-07-23 18:48:41 +0000493 return false;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000494
495 // D must be either a member field or global (potentially shared) variable.
496 if (!mayBeSharedVariable(D)) {
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000497 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
498 << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
Michael Han3be3b442012-07-23 18:48:41 +0000499 return false;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000500 }
501
Michael Han3be3b442012-07-23 18:48:41 +0000502 return true;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000503}
504
Michael Han3be3b442012-07-23 18:48:41 +0000505static void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr) {
506 if (!checkGuardedVarAttrCommon(S, D, Attr))
507 return;
Michael Hana9171bc2012-08-03 17:40:43 +0000508
Michael Han99315932013-01-24 16:46:58 +0000509 D->addAttr(::new (S.Context)
510 GuardedVarAttr(Attr.getRange(), S.Context,
511 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000512}
513
Michael Hana9171bc2012-08-03 17:40:43 +0000514static void handlePtGuardedVarAttr(Sema &S, Decl *D,
Michael Han99315932013-01-24 16:46:58 +0000515 const AttributeList &Attr) {
Michael Han3be3b442012-07-23 18:48:41 +0000516 if (!checkGuardedVarAttrCommon(S, D, Attr))
517 return;
518
519 if (!threadSafetyCheckIsPointer(S, D, Attr))
520 return;
521
Michael Han99315932013-01-24 16:46:58 +0000522 D->addAttr(::new (S.Context)
523 PtGuardedVarAttr(Attr.getRange(), S.Context,
524 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000525}
526
Michael Hana9171bc2012-08-03 17:40:43 +0000527static bool checkGuardedByAttrCommon(Sema &S, Decl *D,
528 const AttributeList &Attr,
Michael Han3be3b442012-07-23 18:48:41 +0000529 Expr* &Arg) {
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000530 assert(!Attr.isInvalid());
531
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000532 if (!checkAttributeNumArgs(S, Attr, 1))
Michael Han3be3b442012-07-23 18:48:41 +0000533 return false;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000534
535 // D must be either a member field or global (potentially shared) variable.
536 if (!mayBeSharedVariable(D)) {
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000537 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
538 << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
Michael Han3be3b442012-07-23 18:48:41 +0000539 return false;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000540 }
541
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000542 SmallVector<Expr*, 1> Args;
543 // check that all arguments are lockable objects
544 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
545 unsigned Size = Args.size();
546 if (Size != 1)
Michael Han3be3b442012-07-23 18:48:41 +0000547 return false;
Michael Hana9171bc2012-08-03 17:40:43 +0000548
Michael Han3be3b442012-07-23 18:48:41 +0000549 Arg = Args[0];
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000550
Michael Han3be3b442012-07-23 18:48:41 +0000551 return true;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000552}
553
Michael Han3be3b442012-07-23 18:48:41 +0000554static void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) {
555 Expr *Arg = 0;
556 if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
557 return;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000558
Michael Han3be3b442012-07-23 18:48:41 +0000559 D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
560}
561
Michael Hana9171bc2012-08-03 17:40:43 +0000562static void handlePtGuardedByAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000563 const AttributeList &Attr) {
564 Expr *Arg = 0;
565 if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
566 return;
567
568 if (!threadSafetyCheckIsPointer(S, D, Attr))
569 return;
570
571 D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
572 S.Context, Arg));
573}
574
Michael Hana9171bc2012-08-03 17:40:43 +0000575static bool checkLockableAttrCommon(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000576 const AttributeList &Attr) {
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000577 assert(!Attr.isInvalid());
578
579 if (!checkAttributeNumArgs(S, Attr, 0))
Michael Han3be3b442012-07-23 18:48:41 +0000580 return false;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000581
Caitlin Sadowski086fb952011-09-16 00:35:54 +0000582 // FIXME: Lockable structs for C code.
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000583 if (!isa<CXXRecordDecl>(D)) {
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000584 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
585 << Attr.getName() << ThreadExpectedClassOrStruct;
Michael Han3be3b442012-07-23 18:48:41 +0000586 return false;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000587 }
588
Michael Han3be3b442012-07-23 18:48:41 +0000589 return true;
590}
591
592static void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
593 if (!checkLockableAttrCommon(S, D, Attr))
594 return;
595
596 D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
597}
598
Michael Hana9171bc2012-08-03 17:40:43 +0000599static void handleScopedLockableAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000600 const AttributeList &Attr) {
601 if (!checkLockableAttrCommon(S, D, Attr))
602 return;
603
Michael Han99315932013-01-24 16:46:58 +0000604 D->addAttr(::new (S.Context)
605 ScopedLockableAttr(Attr.getRange(), S.Context,
606 Attr.getAttributeSpellingListIndex()));
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000607}
608
609static void handleNoThreadSafetyAttr(Sema &S, Decl *D,
610 const AttributeList &Attr) {
611 assert(!Attr.isInvalid());
612
613 if (!checkAttributeNumArgs(S, Attr, 0))
614 return;
615
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000616 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000617 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
618 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000619 return;
620 }
621
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +0000622 D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +0000623 S.Context));
624}
625
Kostya Serebryany588d6ab2012-01-24 19:25:38 +0000626static void handleNoAddressSafetyAttr(Sema &S, Decl *D,
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000627 const AttributeList &Attr) {
Kostya Serebryany588d6ab2012-01-24 19:25:38 +0000628 assert(!Attr.isInvalid());
629
630 if (!checkAttributeNumArgs(S, Attr, 0))
631 return;
632
633 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
634 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
635 << Attr.getName() << ExpectedFunctionOrMethod;
636 return;
637 }
638
Michael Han99315932013-01-24 16:46:58 +0000639 D->addAttr(::new (S.Context)
640 NoAddressSafetyAnalysisAttr(Attr.getRange(), S.Context,
641 Attr.getAttributeSpellingListIndex()));
Kostya Serebryany588d6ab2012-01-24 19:25:38 +0000642}
643
Michael Hana9171bc2012-08-03 17:40:43 +0000644static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
645 const AttributeList &Attr,
Michael Han3be3b442012-07-23 18:48:41 +0000646 SmallVector<Expr*, 1> &Args) {
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000647 assert(!Attr.isInvalid());
648
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000649 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
Michael Han3be3b442012-07-23 18:48:41 +0000650 return false;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000651
652 // D must be either a member field or global (potentially shared) variable.
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000653 ValueDecl *VD = dyn_cast<ValueDecl>(D);
654 if (!VD || !mayBeSharedVariable(D)) {
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000655 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
656 << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
Michael Han3be3b442012-07-23 18:48:41 +0000657 return false;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000658 }
659
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000660 // Check that this attribute only applies to lockable types.
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000661 QualType QT = VD->getType();
662 if (!QT->isDependentType()) {
663 const RecordType *RT = getRecordType(QT);
664 if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000665 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
Michael Han3be3b442012-07-23 18:48:41 +0000666 << Attr.getName();
667 return false;
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000668 }
669 }
670
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000671 // Check that all arguments are lockable objects.
672 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
Michael Han3be3b442012-07-23 18:48:41 +0000673 if (Args.size() == 0)
674 return false;
Michael Hana9171bc2012-08-03 17:40:43 +0000675
Michael Han3be3b442012-07-23 18:48:41 +0000676 return true;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000677}
678
Michael Hana9171bc2012-08-03 17:40:43 +0000679static void handleAcquiredAfterAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000680 const AttributeList &Attr) {
681 SmallVector<Expr*, 1> Args;
682 if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
683 return;
684
685 Expr **StartArg = &Args[0];
Michael Han99315932013-01-24 16:46:58 +0000686 D->addAttr(::new (S.Context)
687 AcquiredAfterAttr(Attr.getRange(), S.Context,
688 StartArg, Args.size(),
689 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000690}
691
Michael Hana9171bc2012-08-03 17:40:43 +0000692static void handleAcquiredBeforeAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000693 const AttributeList &Attr) {
694 SmallVector<Expr*, 1> Args;
695 if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
696 return;
697
698 Expr **StartArg = &Args[0];
Michael Han99315932013-01-24 16:46:58 +0000699 D->addAttr(::new (S.Context)
700 AcquiredBeforeAttr(Attr.getRange(), S.Context,
701 StartArg, Args.size(),
702 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000703}
704
Michael Hana9171bc2012-08-03 17:40:43 +0000705static bool checkLockFunAttrCommon(Sema &S, Decl *D,
706 const AttributeList &Attr,
Michael Han3be3b442012-07-23 18:48:41 +0000707 SmallVector<Expr*, 1> &Args) {
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000708 assert(!Attr.isInvalid());
709
710 // zero or more arguments ok
711
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000712 // check that the attribute is applied to a function
713 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000714 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
715 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Michael Han3be3b442012-07-23 18:48:41 +0000716 return false;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000717 }
718
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000719 // check that all arguments are lockable objects
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000720 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000721
Michael Han3be3b442012-07-23 18:48:41 +0000722 return true;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000723}
724
Michael Hana9171bc2012-08-03 17:40:43 +0000725static void handleSharedLockFunctionAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000726 const AttributeList &Attr) {
727 SmallVector<Expr*, 1> Args;
728 if (!checkLockFunAttrCommon(S, D, Attr, Args))
729 return;
730
731 unsigned Size = Args.size();
732 Expr **StartArg = Size == 0 ? 0 : &Args[0];
Michael Han99315932013-01-24 16:46:58 +0000733 D->addAttr(::new (S.Context)
734 SharedLockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
735 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000736}
737
Michael Hana9171bc2012-08-03 17:40:43 +0000738static void handleExclusiveLockFunctionAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000739 const AttributeList &Attr) {
740 SmallVector<Expr*, 1> Args;
741 if (!checkLockFunAttrCommon(S, D, Attr, Args))
742 return;
743
744 unsigned Size = Args.size();
745 Expr **StartArg = Size == 0 ? 0 : &Args[0];
Michael Han99315932013-01-24 16:46:58 +0000746 D->addAttr(::new (S.Context)
747 ExclusiveLockFunctionAttr(Attr.getRange(), S.Context,
748 StartArg, Size,
749 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000750}
751
Michael Hana9171bc2012-08-03 17:40:43 +0000752static bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
753 const AttributeList &Attr,
Michael Han3be3b442012-07-23 18:48:41 +0000754 SmallVector<Expr*, 2> &Args) {
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000755 assert(!Attr.isInvalid());
756
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000757 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
Michael Han3be3b442012-07-23 18:48:41 +0000758 return false;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000759
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000760 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000761 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
762 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Michael Han3be3b442012-07-23 18:48:41 +0000763 return false;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000764 }
765
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000766 if (!isIntOrBool(Attr.getArg(0))) {
767 S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool)
Michael Han3be3b442012-07-23 18:48:41 +0000768 << Attr.getName();
769 return false;
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000770 }
771
772 // check that all arguments are lockable objects
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000773 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000774
Michael Han3be3b442012-07-23 18:48:41 +0000775 return true;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000776}
777
Michael Hana9171bc2012-08-03 17:40:43 +0000778static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000779 const AttributeList &Attr) {
780 SmallVector<Expr*, 2> Args;
781 if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
782 return;
783
784 unsigned Size = Args.size();
785 Expr **StartArg = Size == 0 ? 0 : &Args[0];
Michael Han99315932013-01-24 16:46:58 +0000786 D->addAttr(::new (S.Context)
787 SharedTrylockFunctionAttr(Attr.getRange(), S.Context,
788 Attr.getArg(0), StartArg, Size,
789 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000790}
791
Michael Hana9171bc2012-08-03 17:40:43 +0000792static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000793 const AttributeList &Attr) {
794 SmallVector<Expr*, 2> Args;
795 if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
796 return;
797
798 unsigned Size = Args.size();
799 Expr **StartArg = Size == 0 ? 0 : &Args[0];
Michael Han99315932013-01-24 16:46:58 +0000800 D->addAttr(::new (S.Context)
801 ExclusiveTrylockFunctionAttr(Attr.getRange(), S.Context,
802 Attr.getArg(0), StartArg, Size,
803 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000804}
805
Michael Hana9171bc2012-08-03 17:40:43 +0000806static bool checkLocksRequiredCommon(Sema &S, Decl *D,
807 const AttributeList &Attr,
Michael Han3be3b442012-07-23 18:48:41 +0000808 SmallVector<Expr*, 1> &Args) {
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000809 assert(!Attr.isInvalid());
810
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000811 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
Michael Han3be3b442012-07-23 18:48:41 +0000812 return false;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000813
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000814 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000815 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
816 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Michael Han3be3b442012-07-23 18:48:41 +0000817 return false;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000818 }
819
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000820 // check that all arguments are lockable objects
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000821 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
Michael Han3be3b442012-07-23 18:48:41 +0000822 if (Args.size() == 0)
823 return false;
Michael Hana9171bc2012-08-03 17:40:43 +0000824
Michael Han3be3b442012-07-23 18:48:41 +0000825 return true;
826}
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000827
Michael Hana9171bc2012-08-03 17:40:43 +0000828static void handleExclusiveLocksRequiredAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000829 const AttributeList &Attr) {
830 SmallVector<Expr*, 1> Args;
831 if (!checkLocksRequiredCommon(S, D, Attr, Args))
832 return;
833
834 Expr **StartArg = &Args[0];
Michael Han99315932013-01-24 16:46:58 +0000835 D->addAttr(::new (S.Context)
836 ExclusiveLocksRequiredAttr(Attr.getRange(), S.Context,
837 StartArg, Args.size(),
838 Attr.getAttributeSpellingListIndex()));
Michael Han3be3b442012-07-23 18:48:41 +0000839}
840
Michael Hana9171bc2012-08-03 17:40:43 +0000841static void handleSharedLocksRequiredAttr(Sema &S, Decl *D,
Michael Han3be3b442012-07-23 18:48:41 +0000842 const AttributeList &Attr) {
843 SmallVector<Expr*, 1> Args;
844 if (!checkLocksRequiredCommon(S, D, Attr, Args))
845 return;
846
847 Expr **StartArg = &Args[0];
Michael Han99315932013-01-24 16:46:58 +0000848 D->addAttr(::new (S.Context)
849 SharedLocksRequiredAttr(Attr.getRange(), S.Context,
850 StartArg, Args.size(),
851 Attr.getAttributeSpellingListIndex()));
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000852}
853
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000854static void handleUnlockFunAttr(Sema &S, Decl *D,
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000855 const AttributeList &Attr) {
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000856 assert(!Attr.isInvalid());
857
858 // zero or more arguments ok
859
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000860 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000861 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
862 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000863 return;
864 }
865
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000866 // check that all arguments are lockable objects
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000867 SmallVector<Expr*, 1> Args;
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000868 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000869 unsigned Size = Args.size();
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000870 Expr **StartArg = Size == 0 ? 0 : &Args[0];
871
Michael Han99315932013-01-24 16:46:58 +0000872 D->addAttr(::new (S.Context)
873 UnlockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
874 Attr.getAttributeSpellingListIndex()));
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000875}
876
877static void handleLockReturnedAttr(Sema &S, Decl *D,
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000878 const AttributeList &Attr) {
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000879 assert(!Attr.isInvalid());
880
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000881 if (!checkAttributeNumArgs(S, Attr, 1))
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000882 return;
883
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000884 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000885 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
886 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000887 return;
888 }
889
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000890 // check that the argument is lockable object
DeLesley Hutchinsd96b46a2012-05-02 17:38:37 +0000891 SmallVector<Expr*, 1> Args;
892 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
893 unsigned Size = Args.size();
894 if (Size == 0)
895 return;
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000896
Michael Han99315932013-01-24 16:46:58 +0000897 D->addAttr(::new (S.Context)
898 LockReturnedAttr(Attr.getRange(), S.Context, Args[0],
899 Attr.getAttributeSpellingListIndex()));
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000900}
901
902static void handleLocksExcludedAttr(Sema &S, Decl *D,
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000903 const AttributeList &Attr) {
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000904 assert(!Attr.isInvalid());
905
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000906 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000907 return;
908
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000909 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins312e7422012-06-19 23:25:19 +0000910 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
911 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000912 return;
913 }
914
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000915 // check that all arguments are lockable objects
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000916 SmallVector<Expr*, 1> Args;
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000917 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000918 unsigned Size = Args.size();
DeLesley Hutchins8d11c792012-04-19 16:10:44 +0000919 if (Size == 0)
920 return;
921 Expr **StartArg = &Args[0];
Caitlin Sadowskiafbbd8e2011-08-23 18:46:34 +0000922
Michael Han99315932013-01-24 16:46:58 +0000923 D->addAttr(::new (S.Context)
924 LocksExcludedAttr(Attr.getRange(), S.Context, StartArg, Size,
925 Attr.getAttributeSpellingListIndex()));
Caitlin Sadowski63fa6672011-07-28 20:12:35 +0000926}
927
928
Chandler Carruthedc2c642011-07-02 00:01:44 +0000929static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
930 const AttributeList &Attr) {
Richard Smith1f5a4322013-01-13 02:11:23 +0000931 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
932 if (TD == 0) {
933 // __attribute__((ext_vector_type(N))) can only be applied to typedefs
934 // and type-ids.
Chris Lattnerb632a6e2008-06-29 00:43:07 +0000935 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
Chris Lattner4a927cb2008-06-28 23:36:30 +0000936 return;
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000937 }
Mike Stumpd3bb5572009-07-24 19:02:52 +0000938
Richard Smith1f5a4322013-01-13 02:11:23 +0000939 // Remember this typedef decl, we will need it later for diagnostics.
940 S.ExtVectorDecls.push_back(TD);
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000941}
942
Chandler Carruthedc2c642011-07-02 00:01:44 +0000943static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000944 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +0000945 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000946 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +0000947
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000948 if (TagDecl *TD = dyn_cast<TagDecl>(D))
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +0000949 TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000950 else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000951 // If the alignment is less than or equal to 8 bits, the packed attribute
952 // has no effect.
Eli Friedmanc087c3f2012-11-07 00:35:20 +0000953 if (!FD->getType()->isDependentType() &&
954 !FD->getType()->isIncompleteType() &&
Chris Lattnerb632a6e2008-06-29 00:43:07 +0000955 S.Context.getTypeAlign(FD->getType()) <= 8)
Chris Lattner3b054132008-11-19 05:08:23 +0000956 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
Chris Lattnere3d20d92008-11-23 21:45:46 +0000957 << Attr.getName() << FD->getType();
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000958 else
Michael Han99315932013-01-24 16:46:58 +0000959 FD->addAttr(::new (S.Context)
960 PackedAttr(Attr.getRange(), S.Context,
961 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000962 } else
Chris Lattner4bd8dd82008-11-19 08:23:25 +0000963 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
Chris Lattner2c6fcf52008-06-26 18:38:35 +0000964}
965
Chandler Carruthedc2c642011-07-02 00:01:44 +0000966static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Eli Friedman9ee2d0472012-10-12 23:29:20 +0000967 if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
Michael Han99315932013-01-24 16:46:58 +0000968 RD->addAttr(::new (S.Context)
969 MsStructAttr(Attr.getRange(), S.Context,
970 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanian6b4e26b2011-04-26 17:54:40 +0000971 else
972 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
973}
974
Chandler Carruthedc2c642011-07-02 00:01:44 +0000975static void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
Ted Kremenek8e3704d2008-07-15 22:26:48 +0000976 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +0000977 if (!checkAttributeNumArgs(S, Attr, 0))
Ted Kremenek8e3704d2008-07-15 22:26:48 +0000978 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +0000979
Ted Kremenek1f672822010-02-18 03:08:58 +0000980 // The IBAction attributes only apply to instance methods.
Chandler Carruthff4c4f02011-07-01 23:49:12 +0000981 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Ted Kremenek1f672822010-02-18 03:08:58 +0000982 if (MD->isInstanceMethod()) {
Michael Han99315932013-01-24 16:46:58 +0000983 D->addAttr(::new (S.Context)
984 IBActionAttr(Attr.getRange(), S.Context,
985 Attr.getAttributeSpellingListIndex()));
Ted Kremenek1f672822010-02-18 03:08:58 +0000986 return;
987 }
988
Ted Kremenekd68ec812011-02-04 06:54:16 +0000989 S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
Ted Kremenek1f672822010-02-18 03:08:58 +0000990}
991
Ted Kremenek7fd17232011-09-29 07:02:25 +0000992static bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
993 // The IBOutlet/IBOutletCollection attributes only apply to instance
994 // variables or properties of Objective-C classes. The outlet must also
995 // have an object reference type.
996 if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
997 if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
Ted Kremenek5d6044e2011-11-01 18:08:35 +0000998 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
Ted Kremenek7fd17232011-09-29 07:02:25 +0000999 << Attr.getName() << VD->getType() << 0;
1000 return false;
1001 }
1002 }
1003 else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1004 if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
Douglas Gregor5c3cc422012-03-14 16:55:17 +00001005 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
Ted Kremenek7fd17232011-09-29 07:02:25 +00001006 << Attr.getName() << PD->getType() << 1;
1007 return false;
1008 }
1009 }
1010 else {
1011 S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
1012 return false;
1013 }
Douglas Gregor5c3cc422012-03-14 16:55:17 +00001014
Ted Kremenek7fd17232011-09-29 07:02:25 +00001015 return true;
1016}
1017
Chandler Carruthedc2c642011-07-02 00:01:44 +00001018static void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
Ted Kremenek1f672822010-02-18 03:08:58 +00001019 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00001020 if (!checkAttributeNumArgs(S, Attr, 0))
Ted Kremenek1f672822010-02-18 03:08:58 +00001021 return;
Ted Kremenek7fd17232011-09-29 07:02:25 +00001022
1023 if (!checkIBOutletCommon(S, D, Attr))
Ted Kremenek1f672822010-02-18 03:08:58 +00001024 return;
Ted Kremenek1f672822010-02-18 03:08:58 +00001025
Michael Han99315932013-01-24 16:46:58 +00001026 D->addAttr(::new (S.Context)
1027 IBOutletAttr(Attr.getRange(), S.Context,
1028 Attr.getAttributeSpellingListIndex()));
Ted Kremenek8e3704d2008-07-15 22:26:48 +00001029}
1030
Chandler Carruthedc2c642011-07-02 00:01:44 +00001031static void handleIBOutletCollection(Sema &S, Decl *D,
1032 const AttributeList &Attr) {
Ted Kremenek26bde772010-05-19 17:38:06 +00001033
1034 // The iboutletcollection attribute can have zero or one arguments.
Fariborz Jahanianb5d59b62010-08-17 20:23:12 +00001035 if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
Ted Kremenek26bde772010-05-19 17:38:06 +00001036 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1037 return;
1038 }
1039
Ted Kremenek7fd17232011-09-29 07:02:25 +00001040 if (!checkIBOutletCommon(S, D, Attr))
Ted Kremenek26bde772010-05-19 17:38:06 +00001041 return;
Ted Kremenek7fd17232011-09-29 07:02:25 +00001042
Fariborz Jahanianb5d59b62010-08-17 20:23:12 +00001043 IdentifierInfo *II = Attr.getParameterName();
1044 if (!II)
Fariborz Jahanian2f31b332011-10-18 19:54:31 +00001045 II = &S.Context.Idents.get("NSObject");
Fariborz Jahanian798f8322010-08-17 21:39:27 +00001046
John McCallba7bf592010-08-24 05:47:05 +00001047 ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001048 S.getScopeForContext(D->getDeclContext()->getParent()));
Fariborz Jahanianb5d59b62010-08-17 20:23:12 +00001049 if (!TypeRep) {
1050 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
1051 return;
1052 }
John McCallba7bf592010-08-24 05:47:05 +00001053 QualType QT = TypeRep.get();
Fariborz Jahanianb5d59b62010-08-17 20:23:12 +00001054 // Diagnose use of non-object type in iboutletcollection attribute.
1055 // FIXME. Gnu attribute extension ignores use of builtin types in
1056 // attributes. So, __attribute__((iboutletcollection(char))) will be
1057 // treated as __attribute__((iboutletcollection())).
Fariborz Jahanian2f31b332011-10-18 19:54:31 +00001058 if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
Fariborz Jahanianb5d59b62010-08-17 20:23:12 +00001059 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
1060 return;
1061 }
Michael Han99315932013-01-24 16:46:58 +00001062 D->addAttr(::new (S.Context)
1063 IBOutletCollectionAttr(Attr.getRange(),S.Context,
1064 QT, Attr.getParameterLoc(),
1065 Attr.getAttributeSpellingListIndex()));
Ted Kremenek26bde772010-05-19 17:38:06 +00001066}
1067
Chandler Carruth3ed22c32011-07-01 23:49:16 +00001068static void possibleTransparentUnionPointerType(QualType &T) {
Fariborz Jahanianf4aa2792011-06-27 21:12:03 +00001069 if (const RecordType *UT = T->getAsUnionType())
1070 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
1071 RecordDecl *UD = UT->getDecl();
1072 for (RecordDecl::field_iterator it = UD->field_begin(),
1073 itend = UD->field_end(); it != itend; ++it) {
1074 QualType QT = it->getType();
1075 if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
1076 T = QT;
1077 return;
1078 }
1079 }
1080 }
1081}
1082
Nuno Lopes5c7ad162012-05-24 00:22:00 +00001083static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Nuno Lopese881ce22012-06-18 16:39:04 +00001084 if (!isFunctionOrMethod(D)) {
1085 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1086 << "alloc_size" << ExpectedFunctionOrMethod;
1087 return;
1088 }
1089
Nuno Lopes5c7ad162012-05-24 00:22:00 +00001090 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
1091 return;
1092
1093 // In C++ the implicit 'this' function parameter also counts, and they are
1094 // counted from one.
1095 bool HasImplicitThisParam = isInstanceMethod(D);
1096 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1097
1098 SmallVector<unsigned, 8> SizeArgs;
1099
1100 for (AttributeList::arg_iterator I = Attr.arg_begin(),
1101 E = Attr.arg_end(); I!=E; ++I) {
1102 // The argument must be an integer constant expression.
1103 Expr *Ex = *I;
1104 llvm::APSInt ArgNum;
1105 if (Ex->isTypeDependent() || Ex->isValueDependent() ||
1106 !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
1107 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1108 << "alloc_size" << Ex->getSourceRange();
1109 return;
1110 }
1111
1112 uint64_t x = ArgNum.getZExtValue();
1113
1114 if (x < 1 || x > NumArgs) {
1115 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1116 << "alloc_size" << I.getArgNum() << Ex->getSourceRange();
1117 return;
1118 }
1119
1120 --x;
1121 if (HasImplicitThisParam) {
1122 if (x == 0) {
1123 S.Diag(Attr.getLoc(),
1124 diag::err_attribute_invalid_implicit_this_argument)
1125 << "alloc_size" << Ex->getSourceRange();
1126 return;
1127 }
1128 --x;
1129 }
1130
1131 // check if the function argument is of an integer type
1132 QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
1133 if (!T->isIntegerType()) {
1134 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1135 << "alloc_size" << Ex->getSourceRange();
1136 return;
1137 }
1138
Nuno Lopes5c7ad162012-05-24 00:22:00 +00001139 SizeArgs.push_back(x);
1140 }
1141
1142 // check if the function returns a pointer
1143 if (!getFunctionType(D)->getResultType()->isAnyPointerType()) {
1144 S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
1145 << "alloc_size" << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange();
1146 }
1147
Michael Han99315932013-01-24 16:46:58 +00001148 D->addAttr(::new (S.Context)
1149 AllocSizeAttr(Attr.getRange(), S.Context,
1150 SizeArgs.data(), SizeArgs.size(),
1151 Attr.getAttributeSpellingListIndex()));
Nuno Lopes5c7ad162012-05-24 00:22:00 +00001152}
1153
Chandler Carruthedc2c642011-07-02 00:01:44 +00001154static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Mike Stumpd3bb5572009-07-24 19:02:52 +00001155 // GCC ignores the nonnull attribute on K&R style function prototypes, so we
1156 // ignore it as well
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001157 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
Chris Lattner3b054132008-11-19 05:08:23 +00001158 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001159 << Attr.getName() << ExpectedFunction;
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001160 return;
1161 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001162
Chandler Carruth743682b2010-11-16 08:35:43 +00001163 // In C++ the implicit 'this' function parameter also counts, and they are
1164 // counted from one.
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001165 bool HasImplicitThisParam = isInstanceMethod(D);
Nick Lewyckye1121512013-01-24 01:12:16 +00001166 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001167
1168 // The nonnull attribute only applies to pointers.
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001169 SmallVector<unsigned, 10> NonNullArgs;
Mike Stumpd3bb5572009-07-24 19:02:52 +00001170
Nick Lewyckye1121512013-01-24 01:12:16 +00001171 for (AttributeList::arg_iterator I = Attr.arg_begin(),
1172 E = Attr.arg_end(); I != E; ++I) {
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001173 // The argument must be an integer constant expression.
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00001174 Expr *Ex = *I;
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001175 llvm::APSInt ArgNum(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00001176 if (Ex->isTypeDependent() || Ex->isValueDependent() ||
1177 !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
Chris Lattner3b054132008-11-19 05:08:23 +00001178 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1179 << "nonnull" << Ex->getSourceRange();
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001180 return;
1181 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001182
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001183 unsigned x = (unsigned) ArgNum.getZExtValue();
Mike Stumpd3bb5572009-07-24 19:02:52 +00001184
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001185 if (x < 1 || x > NumArgs) {
Chris Lattner3b054132008-11-19 05:08:23 +00001186 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
Chris Lattner91aea712008-11-19 07:22:31 +00001187 << "nonnull" << I.getArgNum() << Ex->getSourceRange();
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001188 return;
1189 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001190
Ted Kremenek5224e6a2008-07-21 22:09:15 +00001191 --x;
Chandler Carruth743682b2010-11-16 08:35:43 +00001192 if (HasImplicitThisParam) {
1193 if (x == 0) {
1194 S.Diag(Attr.getLoc(),
1195 diag::err_attribute_invalid_implicit_this_argument)
1196 << "nonnull" << Ex->getSourceRange();
1197 return;
1198 }
1199 --x;
1200 }
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001201
1202 // Is the function argument a pointer type?
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001203 QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
Chandler Carruth3ed22c32011-07-01 23:49:16 +00001204 possibleTransparentUnionPointerType(T);
Fariborz Jahanianf4aa2792011-06-27 21:12:03 +00001205
Ted Kremenekd4adebb2009-07-15 23:23:54 +00001206 if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001207 // FIXME: Should also highlight argument in decl.
Douglas Gregor62157e52010-08-12 18:48:43 +00001208 S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
Chris Lattner3b054132008-11-19 05:08:23 +00001209 << "nonnull" << Ex->getSourceRange();
Ted Kremenekc4f6d902008-09-01 19:57:52 +00001210 continue;
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001211 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001212
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001213 NonNullArgs.push_back(x);
1214 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001215
1216 // If no arguments were specified to __attribute__((nonnull)) then all pointer
1217 // arguments have a nonnull attribute.
Ted Kremenekc4f6d902008-09-01 19:57:52 +00001218 if (NonNullArgs.empty()) {
Nick Lewyckye1121512013-01-24 01:12:16 +00001219 for (unsigned i = 0, e = getFunctionOrMethodNumArgs(D); i != e; ++i) {
1220 QualType T = getFunctionOrMethodArgType(D, i).getNonReferenceType();
Chandler Carruth3ed22c32011-07-01 23:49:16 +00001221 possibleTransparentUnionPointerType(T);
Ted Kremenekd4adebb2009-07-15 23:23:54 +00001222 if (T->isAnyPointerType() || T->isBlockPointerType())
Nick Lewyckye1121512013-01-24 01:12:16 +00001223 NonNullArgs.push_back(i);
Ted Kremenek5fa50522008-11-18 06:52:58 +00001224 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001225
Ted Kremenek22813f42010-10-21 18:49:36 +00001226 // No pointer arguments?
Fariborz Jahaniancb67d7b2010-09-27 19:05:51 +00001227 if (NonNullArgs.empty()) {
1228 // Warn the trivial case only if attribute is not coming from a
1229 // macro instantiation.
1230 if (Attr.getLoc().isFileID())
1231 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
Ted Kremenekc4f6d902008-09-01 19:57:52 +00001232 return;
Fariborz Jahaniancb67d7b2010-09-27 19:05:51 +00001233 }
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001234 }
Ted Kremenekc4f6d902008-09-01 19:57:52 +00001235
Nick Lewyckye1121512013-01-24 01:12:16 +00001236 unsigned *start = &NonNullArgs[0];
Ted Kremenekc4f6d902008-09-01 19:57:52 +00001237 unsigned size = NonNullArgs.size();
Ted Kremenekd21139a2010-07-31 01:52:11 +00001238 llvm::array_pod_sort(start, start + size);
Michael Han99315932013-01-24 16:46:58 +00001239 D->addAttr(::new (S.Context)
1240 NonNullAttr(Attr.getRange(), S.Context, start, size,
1241 Attr.getAttributeSpellingListIndex()));
Ted Kremenek2d63bc12008-07-21 21:53:04 +00001242}
1243
Chandler Carruthedc2c642011-07-02 00:01:44 +00001244static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
Ted Kremenekd21139a2010-07-31 01:52:11 +00001245 // This attribute must be applied to a function declaration.
1246 // The first argument to the attribute must be a string,
1247 // the name of the resource, for example "malloc".
1248 // The following arguments must be argument indexes, the arguments must be
1249 // of integer type for Returns, otherwise of pointer type.
1250 // The difference between Holds and Takes is that a pointer may still be used
Jordy Rose5af0e3c2010-08-12 08:54:03 +00001251 // after being held. free() should be __attribute((ownership_takes)), whereas
1252 // a list append function may well be __attribute((ownership_holds)).
Ted Kremenekd21139a2010-07-31 01:52:11 +00001253
1254 if (!AL.getParameterName()) {
1255 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
1256 << AL.getName()->getName() << 1;
1257 return;
1258 }
1259 // Figure out our Kind, and check arguments while we're at it.
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001260 OwnershipAttr::OwnershipKind K;
Jordy Rose5af0e3c2010-08-12 08:54:03 +00001261 switch (AL.getKind()) {
1262 case AttributeList::AT_ownership_takes:
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001263 K = OwnershipAttr::Takes;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001264 if (AL.getNumArgs() < 1) {
1265 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1266 return;
1267 }
Jordy Rose5af0e3c2010-08-12 08:54:03 +00001268 break;
1269 case AttributeList::AT_ownership_holds:
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001270 K = OwnershipAttr::Holds;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001271 if (AL.getNumArgs() < 1) {
1272 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1273 return;
1274 }
Jordy Rose5af0e3c2010-08-12 08:54:03 +00001275 break;
1276 case AttributeList::AT_ownership_returns:
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001277 K = OwnershipAttr::Returns;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001278 if (AL.getNumArgs() > 1) {
1279 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
1280 << AL.getNumArgs() + 1;
1281 return;
1282 }
Jordy Rose5af0e3c2010-08-12 08:54:03 +00001283 break;
1284 default:
1285 // This should never happen given how we are called.
1286 llvm_unreachable("Unknown ownership attribute");
Ted Kremenekd21139a2010-07-31 01:52:11 +00001287 }
1288
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001289 if (!isFunction(D) || !hasFunctionProto(D)) {
John McCall5fca7ea2011-03-02 12:29:23 +00001290 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
1291 << AL.getName() << ExpectedFunction;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001292 return;
1293 }
1294
Chandler Carruth743682b2010-11-16 08:35:43 +00001295 // In C++ the implicit 'this' function parameter also counts, and they are
1296 // counted from one.
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001297 bool HasImplicitThisParam = isInstanceMethod(D);
1298 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001299
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001300 StringRef Module = AL.getParameterName()->getName();
Ted Kremenekd21139a2010-07-31 01:52:11 +00001301
1302 // Normalize the argument, __foo__ becomes foo.
1303 if (Module.startswith("__") && Module.endswith("__"))
1304 Module = Module.substr(2, Module.size() - 4);
1305
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001306 SmallVector<unsigned, 10> OwnershipArgs;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001307
Jordy Rose5af0e3c2010-08-12 08:54:03 +00001308 for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
1309 ++I) {
Ted Kremenekd21139a2010-07-31 01:52:11 +00001310
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00001311 Expr *IdxExpr = *I;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001312 llvm::APSInt ArgNum(32);
1313 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1314 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1315 S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
1316 << AL.getName()->getName() << IdxExpr->getSourceRange();
1317 continue;
1318 }
1319
1320 unsigned x = (unsigned) ArgNum.getZExtValue();
1321
1322 if (x > NumArgs || x < 1) {
1323 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
1324 << AL.getName()->getName() << x << IdxExpr->getSourceRange();
1325 continue;
1326 }
1327 --x;
Chandler Carruth743682b2010-11-16 08:35:43 +00001328 if (HasImplicitThisParam) {
1329 if (x == 0) {
1330 S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
1331 << "ownership" << IdxExpr->getSourceRange();
1332 return;
1333 }
1334 --x;
1335 }
1336
Ted Kremenekd21139a2010-07-31 01:52:11 +00001337 switch (K) {
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001338 case OwnershipAttr::Takes:
1339 case OwnershipAttr::Holds: {
Ted Kremenekd21139a2010-07-31 01:52:11 +00001340 // Is the function argument a pointer type?
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001341 QualType T = getFunctionOrMethodArgType(D, x);
Ted Kremenekd21139a2010-07-31 01:52:11 +00001342 if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1343 // FIXME: Should also highlight argument in decl.
1344 S.Diag(AL.getLoc(), diag::err_ownership_type)
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001345 << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
Ted Kremenekd21139a2010-07-31 01:52:11 +00001346 << "pointer"
1347 << IdxExpr->getSourceRange();
1348 continue;
1349 }
1350 break;
1351 }
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001352 case OwnershipAttr::Returns: {
Ted Kremenekd21139a2010-07-31 01:52:11 +00001353 if (AL.getNumArgs() > 1) {
1354 // Is the function argument an integer type?
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00001355 Expr *IdxExpr = AL.getArg(0);
Ted Kremenekd21139a2010-07-31 01:52:11 +00001356 llvm::APSInt ArgNum(32);
1357 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
1358 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
1359 S.Diag(AL.getLoc(), diag::err_ownership_type)
1360 << "ownership_returns" << "integer"
1361 << IdxExpr->getSourceRange();
1362 return;
1363 }
1364 }
1365 break;
1366 }
Ted Kremenekd21139a2010-07-31 01:52:11 +00001367 } // switch
1368
1369 // Check we don't have a conflict with another ownership attribute.
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001370 for (specific_attr_iterator<OwnershipAttr>
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001371 i = D->specific_attr_begin<OwnershipAttr>(),
1372 e = D->specific_attr_end<OwnershipAttr>();
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001373 i != e; ++i) {
1374 if ((*i)->getOwnKind() != K) {
1375 for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
1376 I!=E; ++I) {
1377 if (x == *I) {
1378 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1379 << AL.getName()->getName() << "ownership_*";
Ted Kremenekd21139a2010-07-31 01:52:11 +00001380 }
1381 }
1382 }
1383 }
1384 OwnershipArgs.push_back(x);
1385 }
1386
1387 unsigned* start = OwnershipArgs.data();
1388 unsigned size = OwnershipArgs.size();
1389 llvm::array_pod_sort(start, start + size);
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001390
1391 if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
1392 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
1393 return;
Ted Kremenekd21139a2010-07-31 01:52:11 +00001394 }
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001395
Michael Han99315932013-01-24 16:46:58 +00001396 D->addAttr(::new (S.Context)
1397 OwnershipAttr(AL.getLoc(), S.Context, K, Module, start, size,
1398 AL.getAttributeSpellingListIndex()));
Ted Kremenekd21139a2010-07-31 01:52:11 +00001399}
1400
Chandler Carruthedc2c642011-07-02 00:01:44 +00001401static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Rafael Espindolac18086a2010-02-23 22:00:30 +00001402 // Check the attribute arguments.
1403 if (Attr.getNumArgs() > 1) {
1404 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1405 return;
1406 }
1407
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001408 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
John McCall7a198ce2011-02-08 22:35:49 +00001409 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001410 << Attr.getName() << ExpectedVariableOrFunction;
John McCall7a198ce2011-02-08 22:35:49 +00001411 return;
1412 }
1413
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001414 NamedDecl *nd = cast<NamedDecl>(D);
John McCall7a198ce2011-02-08 22:35:49 +00001415
Rafael Espindolac18086a2010-02-23 22:00:30 +00001416 // gcc rejects
1417 // class c {
1418 // static int a __attribute__((weakref ("v2")));
1419 // static int b() __attribute__((weakref ("f3")));
1420 // };
1421 // and ignores the attributes of
1422 // void f(void) {
1423 // static int a __attribute__((weakref ("v2")));
1424 // }
1425 // we reject them
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001426 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
Sebastian Redl50c68252010-08-31 00:36:30 +00001427 if (!Ctx->isFileContext()) {
1428 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
John McCall7a198ce2011-02-08 22:35:49 +00001429 nd->getNameAsString();
Sebastian Redl50c68252010-08-31 00:36:30 +00001430 return;
Rafael Espindolac18086a2010-02-23 22:00:30 +00001431 }
1432
1433 // The GCC manual says
1434 //
1435 // At present, a declaration to which `weakref' is attached can only
1436 // be `static'.
1437 //
1438 // It also says
1439 //
1440 // Without a TARGET,
1441 // given as an argument to `weakref' or to `alias', `weakref' is
1442 // equivalent to `weak'.
1443 //
1444 // gcc 4.4.1 will accept
1445 // int a7 __attribute__((weakref));
1446 // as
1447 // int a7 __attribute__((weak));
1448 // This looks like a bug in gcc. We reject that for now. We should revisit
1449 // it if this behaviour is actually used.
1450
Rafael Espindolac18086a2010-02-23 22:00:30 +00001451 // GCC rejects
1452 // static ((alias ("y"), weakref)).
1453 // Should we? How to check that weakref is before or after alias?
1454
1455 if (Attr.getNumArgs() == 1) {
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00001456 Expr *Arg = Attr.getArg(0);
Rafael Espindolac18086a2010-02-23 22:00:30 +00001457 Arg = Arg->IgnoreParenCasts();
1458 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1459
Douglas Gregorfb65e592011-07-27 05:40:30 +00001460 if (!Str || !Str->isAscii()) {
Rafael Espindolac18086a2010-02-23 22:00:30 +00001461 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1462 << "weakref" << 1;
1463 return;
1464 }
1465 // GCC will accept anything as the argument of weakref. Should we
1466 // check for an existing decl?
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00001467 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
Eric Christopherbc638a82010-12-01 22:13:54 +00001468 Str->getString()));
Rafael Espindolac18086a2010-02-23 22:00:30 +00001469 }
1470
Michael Han99315932013-01-24 16:46:58 +00001471 D->addAttr(::new (S.Context)
1472 WeakRefAttr(Attr.getRange(), S.Context,
1473 Attr.getAttributeSpellingListIndex()));
Rafael Espindolac18086a2010-02-23 22:00:30 +00001474}
1475
Chandler Carruthedc2c642011-07-02 00:01:44 +00001476static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001477 // check the attribute arguments.
Chris Lattner4a927cb2008-06-28 23:36:30 +00001478 if (Attr.getNumArgs() != 1) {
Chris Lattner4bd8dd82008-11-19 08:23:25 +00001479 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001480 return;
1481 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001482
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00001483 Expr *Arg = Attr.getArg(0);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001484 Arg = Arg->IgnoreParenCasts();
1485 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
Mike Stumpd3bb5572009-07-24 19:02:52 +00001486
Douglas Gregorfb65e592011-07-27 05:40:30 +00001487 if (!Str || !Str->isAscii()) {
Chris Lattner3b054132008-11-19 05:08:23 +00001488 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00001489 << "alias" << 1;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001490 return;
1491 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001492
Douglas Gregore8bbc122011-09-02 00:18:52 +00001493 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
Rafael Espindola0017c5f2010-12-07 15:23:23 +00001494 S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1495 return;
1496 }
1497
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001498 // FIXME: check if target symbol exists in current file
Mike Stumpd3bb5572009-07-24 19:02:52 +00001499
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00001500 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
Michael Han99315932013-01-24 16:46:58 +00001501 Str->getString(),
1502 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001503}
1504
Quentin Colombet4e172062012-11-01 23:55:47 +00001505static void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1506 // Check the attribute arguments.
1507 if (!checkAttributeNumArgs(S, Attr, 0))
1508 return;
1509
1510 if (!isa<FunctionDecl>(D) && !isa<ObjCMethodDecl>(D)) {
1511 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1512 << Attr.getName() << ExpectedFunctionOrMethod;
1513 return;
1514 }
1515
Michael Han99315932013-01-24 16:46:58 +00001516 D->addAttr(::new (S.Context)
1517 MinSizeAttr(Attr.getRange(), S.Context,
1518 Attr.getAttributeSpellingListIndex()));
Quentin Colombet4e172062012-11-01 23:55:47 +00001519}
1520
Benjamin Kramer29c2b432012-05-12 21:10:52 +00001521static void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1522 // Check the attribute arguments.
1523 if (!checkAttributeNumArgs(S, Attr, 0))
1524 return;
1525
1526 if (!isa<FunctionDecl>(D)) {
1527 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1528 << Attr.getName() << ExpectedFunction;
1529 return;
1530 }
1531
1532 if (D->hasAttr<HotAttr>()) {
1533 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1534 << Attr.getName() << "hot";
1535 return;
1536 }
1537
Michael Han99315932013-01-24 16:46:58 +00001538 D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context,
1539 Attr.getAttributeSpellingListIndex()));
Benjamin Kramer29c2b432012-05-12 21:10:52 +00001540}
1541
1542static void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1543 // Check the attribute arguments.
1544 if (!checkAttributeNumArgs(S, Attr, 0))
1545 return;
1546
1547 if (!isa<FunctionDecl>(D)) {
1548 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1549 << Attr.getName() << ExpectedFunction;
1550 return;
1551 }
1552
1553 if (D->hasAttr<ColdAttr>()) {
1554 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1555 << Attr.getName() << "cold";
1556 return;
1557 }
1558
Michael Han99315932013-01-24 16:46:58 +00001559 D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context,
1560 Attr.getAttributeSpellingListIndex()));
Benjamin Kramer29c2b432012-05-12 21:10:52 +00001561}
1562
Chandler Carruthedc2c642011-07-02 00:01:44 +00001563static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar8caf6412010-09-29 18:20:25 +00001564 // Check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00001565 if (!checkAttributeNumArgs(S, Attr, 0))
Daniel Dunbar03a38442008-10-28 00:17:57 +00001566 return;
Anders Carlsson88097122009-02-19 19:16:48 +00001567
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001568 if (!isa<FunctionDecl>(D)) {
Anders Carlsson88097122009-02-19 19:16:48 +00001569 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001570 << Attr.getName() << ExpectedFunction;
Daniel Dunbar8caf6412010-09-29 18:20:25 +00001571 return;
1572 }
1573
Michael Han99315932013-01-24 16:46:58 +00001574 D->addAttr(::new (S.Context)
1575 NakedAttr(Attr.getRange(), S.Context,
1576 Attr.getAttributeSpellingListIndex()));
Daniel Dunbar8caf6412010-09-29 18:20:25 +00001577}
1578
Chandler Carruthedc2c642011-07-02 00:01:44 +00001579static void handleAlwaysInlineAttr(Sema &S, Decl *D,
1580 const AttributeList &Attr) {
Daniel Dunbar8caf6412010-09-29 18:20:25 +00001581 // Check the attribute arguments.
Ted Kremenek1551d552011-04-15 05:49:29 +00001582 if (Attr.hasParameterOrArguments()) {
Daniel Dunbar8caf6412010-09-29 18:20:25 +00001583 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1584 return;
1585 }
1586
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001587 if (!isa<FunctionDecl>(D)) {
Daniel Dunbar8caf6412010-09-29 18:20:25 +00001588 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001589 << Attr.getName() << ExpectedFunction;
Anders Carlsson88097122009-02-19 19:16:48 +00001590 return;
1591 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001592
Michael Han99315932013-01-24 16:46:58 +00001593 D->addAttr(::new (S.Context)
1594 AlwaysInlineAttr(Attr.getRange(), S.Context,
1595 Attr.getAttributeSpellingListIndex()));
Daniel Dunbar03a38442008-10-28 00:17:57 +00001596}
1597
Hans Wennborgd3b01bc2012-06-23 11:51:46 +00001598static void handleTLSModelAttr(Sema &S, Decl *D,
1599 const AttributeList &Attr) {
1600 // Check the attribute arguments.
1601 if (Attr.getNumArgs() != 1) {
1602 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1603 return;
1604 }
1605
1606 Expr *Arg = Attr.getArg(0);
1607 Arg = Arg->IgnoreParenCasts();
1608 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1609
1610 // Check that it is a string.
1611 if (!Str) {
1612 S.Diag(Attr.getLoc(), diag::err_attribute_not_string) << "tls_model";
1613 return;
1614 }
1615
1616 if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->isThreadSpecified()) {
1617 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1618 << Attr.getName() << ExpectedTLSVar;
1619 return;
1620 }
1621
1622 // Check that the value.
1623 StringRef Model = Str->getString();
1624 if (Model != "global-dynamic" && Model != "local-dynamic"
1625 && Model != "initial-exec" && Model != "local-exec") {
1626 S.Diag(Attr.getLoc(), diag::err_attr_tlsmodel_arg);
1627 return;
1628 }
1629
Michael Han99315932013-01-24 16:46:58 +00001630 D->addAttr(::new (S.Context)
1631 TLSModelAttr(Attr.getRange(), S.Context, Model,
1632 Attr.getAttributeSpellingListIndex()));
Hans Wennborgd3b01bc2012-06-23 11:51:46 +00001633}
1634
Chandler Carruthedc2c642011-07-02 00:01:44 +00001635static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar8caf6412010-09-29 18:20:25 +00001636 // Check the attribute arguments.
Ted Kremenek1551d552011-04-15 05:49:29 +00001637 if (Attr.hasParameterOrArguments()) {
Ryan Flynn1f1fdc02009-08-09 20:07:29 +00001638 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1639 return;
1640 }
Mike Stump11289f42009-09-09 15:08:12 +00001641
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001642 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
Mike Stump11289f42009-09-09 15:08:12 +00001643 QualType RetTy = FD->getResultType();
Ted Kremenek08479ae2009-08-15 00:51:46 +00001644 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
Michael Han99315932013-01-24 16:46:58 +00001645 D->addAttr(::new (S.Context)
1646 MallocAttr(Attr.getRange(), S.Context,
1647 Attr.getAttributeSpellingListIndex()));
Ted Kremenek08479ae2009-08-15 00:51:46 +00001648 return;
1649 }
Ryan Flynn1f1fdc02009-08-09 20:07:29 +00001650 }
1651
Ted Kremenek08479ae2009-08-15 00:51:46 +00001652 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
Ryan Flynn1f1fdc02009-08-09 20:07:29 +00001653}
1654
Chandler Carruthedc2c642011-07-02 00:01:44 +00001655static void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Dan Gohmanbbb7d622010-11-17 00:03:07 +00001656 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00001657 if (!checkAttributeNumArgs(S, Attr, 0))
Dan Gohmanbbb7d622010-11-17 00:03:07 +00001658 return;
Dan Gohmanbbb7d622010-11-17 00:03:07 +00001659
Michael Han99315932013-01-24 16:46:58 +00001660 D->addAttr(::new (S.Context)
1661 MayAliasAttr(Attr.getRange(), S.Context,
1662 Attr.getAttributeSpellingListIndex()));
Dan Gohmanbbb7d622010-11-17 00:03:07 +00001663}
1664
Chandler Carruthedc2c642011-07-02 00:01:44 +00001665static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruth9312c642011-07-11 23:33:05 +00001666 assert(!Attr.isInvalid());
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001667 if (isa<VarDecl>(D))
Michael Han99315932013-01-24 16:46:58 +00001668 D->addAttr(::new (S.Context)
1669 NoCommonAttr(Attr.getRange(), S.Context,
1670 Attr.getAttributeSpellingListIndex()));
Eric Christopher515d87f2010-12-03 06:58:14 +00001671 else
1672 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001673 << Attr.getName() << ExpectedVariable;
Eric Christopher8a2ee392010-12-02 02:45:55 +00001674}
1675
Chandler Carruthedc2c642011-07-02 00:01:44 +00001676static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruth9312c642011-07-11 23:33:05 +00001677 assert(!Attr.isInvalid());
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001678 if (isa<VarDecl>(D))
Michael Han99315932013-01-24 16:46:58 +00001679 D->addAttr(::new (S.Context)
1680 CommonAttr(Attr.getRange(), S.Context,
1681 Attr.getAttributeSpellingListIndex()));
Eric Christopher515d87f2010-12-03 06:58:14 +00001682 else
1683 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001684 << Attr.getName() << ExpectedVariable;
Eric Christopher8a2ee392010-12-02 02:45:55 +00001685}
1686
Chandler Carruthedc2c642011-07-02 00:01:44 +00001687static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001688 if (hasDeclarator(D)) return;
John McCall3882ace2011-01-05 12:14:39 +00001689
1690 if (S.CheckNoReturnAttr(attr)) return;
1691
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001692 if (!isa<ObjCMethodDecl>(D)) {
John McCall3882ace2011-01-05 12:14:39 +00001693 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001694 << attr.getName() << ExpectedFunctionOrMethod;
John McCall3882ace2011-01-05 12:14:39 +00001695 return;
1696 }
1697
Michael Han99315932013-01-24 16:46:58 +00001698 D->addAttr(::new (S.Context)
1699 NoReturnAttr(attr.getRange(), S.Context,
1700 attr.getAttributeSpellingListIndex()));
John McCall3882ace2011-01-05 12:14:39 +00001701}
1702
1703bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
Ted Kremenek1551d552011-04-15 05:49:29 +00001704 if (attr.hasParameterOrArguments()) {
John McCall3882ace2011-01-05 12:14:39 +00001705 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1706 attr.setInvalid();
1707 return true;
1708 }
1709
1710 return false;
Ted Kremenek40f4ee72009-04-10 00:01:14 +00001711}
1712
Chandler Carruthedc2c642011-07-02 00:01:44 +00001713static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
1714 const AttributeList &Attr) {
Ted Kremenek5295ce82010-08-19 00:51:58 +00001715
1716 // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1717 // because 'analyzer_noreturn' does not impact the type.
1718
Chandler Carruthfcc48d92011-07-11 23:30:35 +00001719 if(!checkAttributeNumArgs(S, Attr, 0))
1720 return;
Ted Kremenek5295ce82010-08-19 00:51:58 +00001721
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001722 if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
1723 ValueDecl *VD = dyn_cast<ValueDecl>(D);
Ted Kremenek5295ce82010-08-19 00:51:58 +00001724 if (VD == 0 || (!VD->getType()->isBlockPointerType()
1725 && !VD->getType()->isFunctionPointerType())) {
1726 S.Diag(Attr.getLoc(),
Richard Smith89645bc2013-01-02 12:01:23 +00001727 Attr.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type
Ted Kremenek5295ce82010-08-19 00:51:58 +00001728 : diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001729 << Attr.getName() << ExpectedFunctionMethodOrBlock;
Ted Kremenek5295ce82010-08-19 00:51:58 +00001730 return;
1731 }
1732 }
1733
Michael Han99315932013-01-24 16:46:58 +00001734 D->addAttr(::new (S.Context)
1735 AnalyzerNoReturnAttr(Attr.getRange(), S.Context,
1736 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001737}
1738
Richard Smith10876ef2013-01-17 01:30:42 +00001739static void handleCXX11NoReturnAttr(Sema &S, Decl *D,
1740 const AttributeList &Attr) {
1741 // C++11 [dcl.attr.noreturn]p1:
1742 // The attribute may be applied to the declarator-id in a function
1743 // declaration.
1744 FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
1745 if (!FD) {
1746 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1747 << Attr.getName() << ExpectedFunctionOrMethod;
1748 return;
1749 }
1750
Michael Han99315932013-01-24 16:46:58 +00001751 D->addAttr(::new (S.Context)
1752 CXX11NoReturnAttr(Attr.getRange(), S.Context,
1753 Attr.getAttributeSpellingListIndex()));
Richard Smith10876ef2013-01-17 01:30:42 +00001754}
1755
John Thompsoncdb847ba2010-08-09 21:53:52 +00001756// PS3 PPU-specific.
Chandler Carruthedc2c642011-07-02 00:01:44 +00001757static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
John Thompsoncdb847ba2010-08-09 21:53:52 +00001758/*
1759 Returning a Vector Class in Registers
1760
Eric Christopherbc638a82010-12-01 22:13:54 +00001761 According to the PPU ABI specifications, a class with a single member of
1762 vector type is returned in memory when used as the return value of a function.
1763 This results in inefficient code when implementing vector classes. To return
1764 the value in a single vector register, add the vecreturn attribute to the
1765 class definition. This attribute is also applicable to struct types.
John Thompsoncdb847ba2010-08-09 21:53:52 +00001766
1767 Example:
1768
1769 struct Vector
1770 {
1771 __vector float xyzw;
1772 } __attribute__((vecreturn));
1773
1774 Vector Add(Vector lhs, Vector rhs)
1775 {
1776 Vector result;
1777 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
1778 return result; // This will be returned in a register
1779 }
1780*/
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001781 if (!isa<RecordDecl>(D)) {
John Thompsoncdb847ba2010-08-09 21:53:52 +00001782 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001783 << Attr.getName() << ExpectedClass;
John Thompsoncdb847ba2010-08-09 21:53:52 +00001784 return;
1785 }
1786
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001787 if (D->getAttr<VecReturnAttr>()) {
John Thompsoncdb847ba2010-08-09 21:53:52 +00001788 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
1789 return;
1790 }
1791
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001792 RecordDecl *record = cast<RecordDecl>(D);
John Thompson9a587aaa2010-09-18 01:12:07 +00001793 int count = 0;
1794
1795 if (!isa<CXXRecordDecl>(record)) {
1796 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
1797 return;
1798 }
1799
1800 if (!cast<CXXRecordDecl>(record)->isPOD()) {
1801 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
1802 return;
1803 }
1804
Eric Christopherbc638a82010-12-01 22:13:54 +00001805 for (RecordDecl::field_iterator iter = record->field_begin();
1806 iter != record->field_end(); iter++) {
John Thompson9a587aaa2010-09-18 01:12:07 +00001807 if ((count == 1) || !iter->getType()->isVectorType()) {
1808 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
1809 return;
1810 }
1811 count++;
1812 }
1813
Michael Han99315932013-01-24 16:46:58 +00001814 D->addAttr(::new (S.Context)
1815 VecReturnAttr(Attr.getRange(), S.Context,
1816 Attr.getAttributeSpellingListIndex()));
John Thompsoncdb847ba2010-08-09 21:53:52 +00001817}
1818
Richard Smithe233fbf2013-01-28 22:42:45 +00001819static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
1820 const AttributeList &Attr) {
1821 if (isa<ParmVarDecl>(D)) {
1822 // [[carries_dependency]] can only be applied to a parameter if it is a
1823 // parameter of a function declaration or lambda.
1824 if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
1825 S.Diag(Attr.getLoc(),
1826 diag::err_carries_dependency_param_not_function_decl);
1827 return;
1828 }
1829 } else if (!isa<FunctionDecl>(D)) {
Alexis Hunt96d5c762009-11-21 08:43:09 +00001830 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001831 << Attr.getName() << ExpectedFunctionMethodOrParameter;
Alexis Hunt96d5c762009-11-21 08:43:09 +00001832 return;
1833 }
Richard Smithe233fbf2013-01-28 22:42:45 +00001834
1835 D->addAttr(::new (S.Context) CarriesDependencyAttr(
1836 Attr.getRange(), S.Context,
1837 Attr.getAttributeSpellingListIndex()));
Alexis Hunt96d5c762009-11-21 08:43:09 +00001838}
1839
Chandler Carruthedc2c642011-07-02 00:01:44 +00001840static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Ted Kremenek39c59a82008-07-25 04:39:19 +00001841 // check the attribute arguments.
Ted Kremenek1551d552011-04-15 05:49:29 +00001842 if (Attr.hasParameterOrArguments()) {
Chris Lattner4bd8dd82008-11-19 08:23:25 +00001843 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
Ted Kremenek39c59a82008-07-25 04:39:19 +00001844 return;
1845 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001846
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001847 if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
Daniel Jasper429c1342012-06-13 18:31:09 +00001848 !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) {
Chris Lattner3b054132008-11-19 05:08:23 +00001849 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001850 << Attr.getName() << ExpectedVariableFunctionOrLabel;
Ted Kremenek39c59a82008-07-25 04:39:19 +00001851 return;
1852 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001853
Michael Han99315932013-01-24 16:46:58 +00001854 D->addAttr(::new (S.Context)
1855 UnusedAttr(Attr.getRange(), S.Context,
1856 Attr.getAttributeSpellingListIndex()));
Ted Kremenek39c59a82008-07-25 04:39:19 +00001857}
1858
Rafael Espindola70107f92011-10-03 14:59:42 +00001859static void handleReturnsTwiceAttr(Sema &S, Decl *D,
1860 const AttributeList &Attr) {
1861 // check the attribute arguments.
1862 if (Attr.hasParameterOrArguments()) {
1863 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1864 return;
1865 }
1866
1867 if (!isa<FunctionDecl>(D)) {
1868 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1869 << Attr.getName() << ExpectedFunction;
1870 return;
1871 }
1872
Michael Han99315932013-01-24 16:46:58 +00001873 D->addAttr(::new (S.Context)
1874 ReturnsTwiceAttr(Attr.getRange(), S.Context,
1875 Attr.getAttributeSpellingListIndex()));
Rafael Espindola70107f92011-10-03 14:59:42 +00001876}
1877
Chandler Carruthedc2c642011-07-02 00:01:44 +00001878static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbarfee07a02009-02-13 19:23:53 +00001879 // check the attribute arguments.
Ted Kremenek1551d552011-04-15 05:49:29 +00001880 if (Attr.hasParameterOrArguments()) {
Daniel Dunbarfee07a02009-02-13 19:23:53 +00001881 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1882 return;
1883 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001884
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001885 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Daniel Dunbar311bf292009-02-13 22:48:56 +00001886 if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
Daniel Dunbarfee07a02009-02-13 19:23:53 +00001887 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1888 return;
1889 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001890 } else if (!isFunctionOrMethod(D)) {
Daniel Dunbarfee07a02009-02-13 19:23:53 +00001891 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001892 << Attr.getName() << ExpectedVariableOrFunction;
Daniel Dunbarfee07a02009-02-13 19:23:53 +00001893 return;
1894 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001895
Michael Han99315932013-01-24 16:46:58 +00001896 D->addAttr(::new (S.Context)
1897 UsedAttr(Attr.getRange(), S.Context,
1898 Attr.getAttributeSpellingListIndex()));
Daniel Dunbarfee07a02009-02-13 19:23:53 +00001899}
1900
Chandler Carruthedc2c642011-07-02 00:01:44 +00001901static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar032db472008-07-31 22:40:48 +00001902 // check the attribute arguments.
John McCall80ee5962011-03-02 12:15:05 +00001903 if (Attr.getNumArgs() > 1) {
1904 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
Daniel Dunbar032db472008-07-31 22:40:48 +00001905 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00001906 }
Daniel Dunbar032db472008-07-31 22:40:48 +00001907
1908 int priority = 65535; // FIXME: Do not hardcode such constants.
1909 if (Attr.getNumArgs() > 0) {
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00001910 Expr *E = Attr.getArg(0);
Daniel Dunbar032db472008-07-31 22:40:48 +00001911 llvm::APSInt Idx(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00001912 if (E->isTypeDependent() || E->isValueDependent() ||
1913 !E->isIntegerConstantExpr(Idx, S.Context)) {
Chris Lattner3b054132008-11-19 05:08:23 +00001914 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00001915 << "constructor" << 1 << E->getSourceRange();
Daniel Dunbar032db472008-07-31 22:40:48 +00001916 return;
1917 }
1918 priority = Idx.getZExtValue();
1919 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001920
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001921 if (!isa<FunctionDecl>(D)) {
Chris Lattner3b054132008-11-19 05:08:23 +00001922 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001923 << Attr.getName() << ExpectedFunction;
Daniel Dunbar032db472008-07-31 22:40:48 +00001924 return;
1925 }
1926
Michael Han99315932013-01-24 16:46:58 +00001927 D->addAttr(::new (S.Context)
1928 ConstructorAttr(Attr.getRange(), S.Context, priority,
1929 Attr.getAttributeSpellingListIndex()));
Daniel Dunbar032db472008-07-31 22:40:48 +00001930}
1931
Chandler Carruthedc2c642011-07-02 00:01:44 +00001932static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar032db472008-07-31 22:40:48 +00001933 // check the attribute arguments.
John McCall80ee5962011-03-02 12:15:05 +00001934 if (Attr.getNumArgs() > 1) {
1935 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
Daniel Dunbar032db472008-07-31 22:40:48 +00001936 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00001937 }
Daniel Dunbar032db472008-07-31 22:40:48 +00001938
1939 int priority = 65535; // FIXME: Do not hardcode such constants.
1940 if (Attr.getNumArgs() > 0) {
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00001941 Expr *E = Attr.getArg(0);
Daniel Dunbar032db472008-07-31 22:40:48 +00001942 llvm::APSInt Idx(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00001943 if (E->isTypeDependent() || E->isValueDependent() ||
1944 !E->isIntegerConstantExpr(Idx, S.Context)) {
Chris Lattner3b054132008-11-19 05:08:23 +00001945 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00001946 << "destructor" << 1 << E->getSourceRange();
Daniel Dunbar032db472008-07-31 22:40:48 +00001947 return;
1948 }
1949 priority = Idx.getZExtValue();
1950 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001951
Chandler Carruthff4c4f02011-07-01 23:49:12 +00001952 if (!isa<FunctionDecl>(D)) {
Chris Lattner3b054132008-11-19 05:08:23 +00001953 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00001954 << Attr.getName() << ExpectedFunction;
Daniel Dunbar032db472008-07-31 22:40:48 +00001955 return;
1956 }
1957
Michael Han99315932013-01-24 16:46:58 +00001958 D->addAttr(::new (S.Context)
1959 DestructorAttr(Attr.getRange(), S.Context, priority,
1960 Attr.getAttributeSpellingListIndex()));
Daniel Dunbar032db472008-07-31 22:40:48 +00001961}
1962
Benjamin Kramerf435ab42012-05-16 12:19:08 +00001963template <typename AttrTy>
1964static void handleAttrWithMessage(Sema &S, Decl *D, const AttributeList &Attr,
1965 const char *Name) {
Chris Lattner190aa102011-02-24 05:42:24 +00001966 unsigned NumArgs = Attr.getNumArgs();
1967 if (NumArgs > 1) {
John McCall80ee5962011-03-02 12:15:05 +00001968 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00001969 return;
1970 }
Benjamin Kramerf435ab42012-05-16 12:19:08 +00001971
1972 // Handle the case where the attribute has a text message.
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001973 StringRef Str;
Chris Lattner190aa102011-02-24 05:42:24 +00001974 if (NumArgs == 1) {
1975 StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
Fariborz Jahanian551063102010-10-06 21:18:44 +00001976 if (!SE) {
Chris Lattner190aa102011-02-24 05:42:24 +00001977 S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
Benjamin Kramerf435ab42012-05-16 12:19:08 +00001978 << Name;
Fariborz Jahanian551063102010-10-06 21:18:44 +00001979 return;
1980 }
Chris Lattner190aa102011-02-24 05:42:24 +00001981 Str = SE->getString();
Fariborz Jahanian551063102010-10-06 21:18:44 +00001982 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00001983
Michael Han99315932013-01-24 16:46:58 +00001984 D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str,
1985 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanian1470e932008-12-17 01:07:27 +00001986}
1987
Fariborz Jahanian1f626d62011-07-06 19:24:05 +00001988static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1989 const AttributeList &Attr) {
1990 unsigned NumArgs = Attr.getNumArgs();
1991 if (NumArgs > 0) {
1992 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1993 return;
1994 }
1995
Michael Han99315932013-01-24 16:46:58 +00001996 D->addAttr(::new (S.Context)
1997 ArcWeakrefUnavailableAttr(Attr.getRange(), S.Context,
1998 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanian1f626d62011-07-06 19:24:05 +00001999}
2000
Patrick Beardacfbe9e2012-04-06 18:12:22 +00002001static void handleObjCRootClassAttr(Sema &S, Decl *D,
2002 const AttributeList &Attr) {
2003 if (!isa<ObjCInterfaceDecl>(D)) {
2004 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
2005 return;
2006 }
2007
2008 unsigned NumArgs = Attr.getNumArgs();
2009 if (NumArgs > 0) {
2010 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
2011 return;
2012 }
2013
Michael Han99315932013-01-24 16:46:58 +00002014 D->addAttr(::new (S.Context)
2015 ObjCRootClassAttr(Attr.getRange(), S.Context,
2016 Attr.getAttributeSpellingListIndex()));
Patrick Beardacfbe9e2012-04-06 18:12:22 +00002017}
2018
Michael Han99315932013-01-24 16:46:58 +00002019static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
2020 const AttributeList &Attr) {
Fariborz Jahanian7249e362012-01-03 22:52:32 +00002021 if (!isa<ObjCInterfaceDecl>(D)) {
2022 S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
2023 return;
2024 }
2025
Fariborz Jahanian9d4d20a2012-01-03 18:45:41 +00002026 unsigned NumArgs = Attr.getNumArgs();
2027 if (NumArgs > 0) {
2028 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
2029 return;
2030 }
2031
Michael Han99315932013-01-24 16:46:58 +00002032 D->addAttr(::new (S.Context)
2033 ObjCRequiresPropertyDefsAttr(Attr.getRange(), S.Context,
2034 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanian9d4d20a2012-01-03 18:45:41 +00002035}
2036
Jordy Rose740b0c22012-05-08 03:27:22 +00002037static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
2038 IdentifierInfo *Platform,
2039 VersionTuple Introduced,
2040 VersionTuple Deprecated,
2041 VersionTuple Obsoleted) {
Rafael Espindola2d243bf2012-05-06 19:56:25 +00002042 StringRef PlatformName
2043 = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2044 if (PlatformName.empty())
2045 PlatformName = Platform->getName();
2046
2047 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2048 // of these steps are needed).
2049 if (!Introduced.empty() && !Deprecated.empty() &&
2050 !(Introduced <= Deprecated)) {
2051 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2052 << 1 << PlatformName << Deprecated.getAsString()
2053 << 0 << Introduced.getAsString();
2054 return true;
2055 }
2056
2057 if (!Introduced.empty() && !Obsoleted.empty() &&
2058 !(Introduced <= Obsoleted)) {
2059 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2060 << 2 << PlatformName << Obsoleted.getAsString()
2061 << 0 << Introduced.getAsString();
2062 return true;
2063 }
2064
2065 if (!Deprecated.empty() && !Obsoleted.empty() &&
2066 !(Deprecated <= Obsoleted)) {
2067 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2068 << 2 << PlatformName << Obsoleted.getAsString()
2069 << 1 << Deprecated.getAsString();
2070 return true;
2071 }
2072
2073 return false;
2074}
2075
Douglas Gregor66a8ca02013-01-15 22:43:08 +00002076/// \brief Check whether the two versions match.
2077///
2078/// If either version tuple is empty, then they are assumed to match. If
2079/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2080static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
2081 bool BeforeIsOkay) {
2082 if (X.empty() || Y.empty())
2083 return true;
2084
2085 if (X == Y)
2086 return true;
2087
2088 if (BeforeIsOkay && X < Y)
2089 return true;
2090
2091 return false;
2092}
2093
Rafael Espindolaa3aea432013-01-08 22:04:34 +00002094AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002095 IdentifierInfo *Platform,
2096 VersionTuple Introduced,
2097 VersionTuple Deprecated,
2098 VersionTuple Obsoleted,
2099 bool IsUnavailable,
Douglas Gregor66a8ca02013-01-15 22:43:08 +00002100 StringRef Message,
Michael Han99315932013-01-24 16:46:58 +00002101 bool Override,
2102 unsigned AttrSpellingListIndex) {
Rafael Espindolac67f2232012-05-10 02:50:16 +00002103 VersionTuple MergedIntroduced = Introduced;
2104 VersionTuple MergedDeprecated = Deprecated;
2105 VersionTuple MergedObsoleted = Obsoleted;
Rafael Espindola2d243bf2012-05-06 19:56:25 +00002106 bool FoundAny = false;
2107
Rafael Espindolac67f2232012-05-10 02:50:16 +00002108 if (D->hasAttrs()) {
2109 AttrVec &Attrs = D->getAttrs();
2110 for (unsigned i = 0, e = Attrs.size(); i != e;) {
2111 const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
2112 if (!OldAA) {
2113 ++i;
2114 continue;
2115 }
Rafael Espindola2d243bf2012-05-06 19:56:25 +00002116
Rafael Espindolac67f2232012-05-10 02:50:16 +00002117 IdentifierInfo *OldPlatform = OldAA->getPlatform();
2118 if (OldPlatform != Platform) {
2119 ++i;
2120 continue;
2121 }
2122
2123 FoundAny = true;
2124 VersionTuple OldIntroduced = OldAA->getIntroduced();
2125 VersionTuple OldDeprecated = OldAA->getDeprecated();
2126 VersionTuple OldObsoleted = OldAA->getObsoleted();
2127 bool OldIsUnavailable = OldAA->getUnavailable();
Rafael Espindolac67f2232012-05-10 02:50:16 +00002128
Douglas Gregor66a8ca02013-01-15 22:43:08 +00002129 if (!versionsMatch(OldIntroduced, Introduced, Override) ||
2130 !versionsMatch(Deprecated, OldDeprecated, Override) ||
2131 !versionsMatch(Obsoleted, OldObsoleted, Override) ||
2132 !(OldIsUnavailable == IsUnavailable ||
Douglas Gregor43dc0c72013-01-16 00:54:48 +00002133 (Override && !OldIsUnavailable && IsUnavailable))) {
Douglas Gregor66a8ca02013-01-15 22:43:08 +00002134 if (Override) {
2135 int Which = -1;
2136 VersionTuple FirstVersion;
2137 VersionTuple SecondVersion;
2138 if (!versionsMatch(OldIntroduced, Introduced, Override)) {
2139 Which = 0;
2140 FirstVersion = OldIntroduced;
2141 SecondVersion = Introduced;
2142 } else if (!versionsMatch(Deprecated, OldDeprecated, Override)) {
2143 Which = 1;
2144 FirstVersion = Deprecated;
2145 SecondVersion = OldDeprecated;
2146 } else if (!versionsMatch(Obsoleted, OldObsoleted, Override)) {
2147 Which = 2;
2148 FirstVersion = Obsoleted;
2149 SecondVersion = OldObsoleted;
2150 }
2151
2152 if (Which == -1) {
2153 Diag(OldAA->getLocation(),
2154 diag::warn_mismatched_availability_override_unavail)
2155 << AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2156 } else {
2157 Diag(OldAA->getLocation(),
2158 diag::warn_mismatched_availability_override)
2159 << Which
2160 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2161 << FirstVersion.getAsString() << SecondVersion.getAsString();
2162 }
2163 Diag(Range.getBegin(), diag::note_overridden_method);
2164 } else {
2165 Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2166 Diag(Range.getBegin(), diag::note_previous_attribute);
2167 }
2168
Rafael Espindolac67f2232012-05-10 02:50:16 +00002169 Attrs.erase(Attrs.begin() + i);
2170 --e;
2171 continue;
2172 }
2173
2174 VersionTuple MergedIntroduced2 = MergedIntroduced;
2175 VersionTuple MergedDeprecated2 = MergedDeprecated;
2176 VersionTuple MergedObsoleted2 = MergedObsoleted;
2177
2178 if (MergedIntroduced2.empty())
2179 MergedIntroduced2 = OldIntroduced;
2180 if (MergedDeprecated2.empty())
2181 MergedDeprecated2 = OldDeprecated;
2182 if (MergedObsoleted2.empty())
2183 MergedObsoleted2 = OldObsoleted;
2184
2185 if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
2186 MergedIntroduced2, MergedDeprecated2,
2187 MergedObsoleted2)) {
2188 Attrs.erase(Attrs.begin() + i);
2189 --e;
2190 continue;
2191 }
2192
2193 MergedIntroduced = MergedIntroduced2;
2194 MergedDeprecated = MergedDeprecated2;
2195 MergedObsoleted = MergedObsoleted2;
2196 ++i;
Rafael Espindola2d243bf2012-05-06 19:56:25 +00002197 }
Rafael Espindola2d243bf2012-05-06 19:56:25 +00002198 }
2199
2200 if (FoundAny &&
2201 MergedIntroduced == Introduced &&
2202 MergedDeprecated == Deprecated &&
2203 MergedObsoleted == Obsoleted)
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002204 return NULL;
Rafael Espindola2d243bf2012-05-06 19:56:25 +00002205
Rafael Espindolac67f2232012-05-10 02:50:16 +00002206 if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
Rafael Espindola2d243bf2012-05-06 19:56:25 +00002207 MergedDeprecated, MergedObsoleted)) {
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002208 return ::new (Context) AvailabilityAttr(Range, Context, Platform,
2209 Introduced, Deprecated,
Michael Han99315932013-01-24 16:46:58 +00002210 Obsoleted, IsUnavailable, Message,
2211 AttrSpellingListIndex);
Rafael Espindola2d243bf2012-05-06 19:56:25 +00002212 }
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002213 return NULL;
Rafael Espindola2d243bf2012-05-06 19:56:25 +00002214}
2215
Chandler Carruthedc2c642011-07-02 00:01:44 +00002216static void handleAvailabilityAttr(Sema &S, Decl *D,
2217 const AttributeList &Attr) {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00002218 IdentifierInfo *Platform = Attr.getParameterName();
2219 SourceLocation PlatformLoc = Attr.getParameterLoc();
Michael Han99315932013-01-24 16:46:58 +00002220 unsigned Index = Attr.getAttributeSpellingListIndex();
2221
Rafael Espindola2d243bf2012-05-06 19:56:25 +00002222 if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty())
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00002223 S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
2224 << Platform;
2225
Rafael Espindolac231fab2013-01-08 21:30:32 +00002226 NamedDecl *ND = dyn_cast<NamedDecl>(D);
2227 if (!ND) {
2228 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2229 return;
2230 }
2231
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00002232 AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
2233 AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
2234 AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
Douglas Gregor7ab142b2011-03-26 03:35:55 +00002235 bool IsUnavailable = Attr.getUnavailableLoc().isValid();
Fariborz Jahanian88d510d2011-12-10 00:28:41 +00002236 StringRef Str;
2237 const StringLiteral *SE =
2238 dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr());
2239 if (SE)
2240 Str = SE->getString();
Rafael Espindola2d243bf2012-05-06 19:56:25 +00002241
Rafael Espindolaa3aea432013-01-08 22:04:34 +00002242 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(),
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002243 Platform,
2244 Introduced.Version,
2245 Deprecated.Version,
2246 Obsoleted.Version,
Douglas Gregor66a8ca02013-01-15 22:43:08 +00002247 IsUnavailable, Str,
Michael Han99315932013-01-24 16:46:58 +00002248 /*Override=*/false,
2249 Index);
Rafael Espindola19de5612013-01-12 06:42:30 +00002250 if (NewAttr)
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002251 D->addAttr(NewAttr);
Rafael Espindolac67f2232012-05-10 02:50:16 +00002252}
2253
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002254VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
Michael Han99315932013-01-24 16:46:58 +00002255 VisibilityAttr::VisibilityType Vis,
2256 unsigned AttrSpellingListIndex) {
Rafael Espindolaa6b3cd42012-05-10 03:01:34 +00002257 if (isa<TypedefNameDecl>(D)) {
2258 Diag(Range.getBegin(), diag::warn_attribute_ignored) << "visibility";
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002259 return NULL;
Rafael Espindolaa6b3cd42012-05-10 03:01:34 +00002260 }
Rafael Espindolac67f2232012-05-10 02:50:16 +00002261 VisibilityAttr *ExistingAttr = D->getAttr<VisibilityAttr>();
2262 if (ExistingAttr) {
2263 VisibilityAttr::VisibilityType ExistingVis = ExistingAttr->getVisibility();
2264 if (ExistingVis == Vis)
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002265 return NULL;
Rafael Espindolac67f2232012-05-10 02:50:16 +00002266 Diag(ExistingAttr->getLocation(), diag::err_mismatched_visibility);
2267 Diag(Range.getBegin(), diag::note_previous_attribute);
2268 D->dropAttr<VisibilityAttr>();
2269 }
Michael Han99315932013-01-24 16:46:58 +00002270 return ::new (Context) VisibilityAttr(Range, Context, Vis,
2271 AttrSpellingListIndex);
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00002272}
2273
Chandler Carruthedc2c642011-07-02 00:01:44 +00002274static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002275 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00002276 if(!checkAttributeNumArgs(S, Attr, 1))
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002277 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002278
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00002279 Expr *Arg = Attr.getArg(0);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002280 Arg = Arg->IgnoreParenCasts();
2281 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
Mike Stumpd3bb5572009-07-24 19:02:52 +00002282
Douglas Gregorfb65e592011-07-27 05:40:30 +00002283 if (!Str || !Str->isAscii()) {
Chris Lattner3b054132008-11-19 05:08:23 +00002284 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00002285 << "visibility" << 1;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002286 return;
2287 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002288
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002289 StringRef TypeStr = Str->getString();
Alexis Huntdcfba7b2010-08-18 23:23:40 +00002290 VisibilityAttr::VisibilityType type;
Michael Han99315932013-01-24 16:46:58 +00002291
Benjamin Kramer12a6ce72010-01-23 18:16:35 +00002292 if (TypeStr == "default")
Alexis Huntdcfba7b2010-08-18 23:23:40 +00002293 type = VisibilityAttr::Default;
Benjamin Kramer12a6ce72010-01-23 18:16:35 +00002294 else if (TypeStr == "hidden")
Alexis Huntdcfba7b2010-08-18 23:23:40 +00002295 type = VisibilityAttr::Hidden;
Benjamin Kramer12a6ce72010-01-23 18:16:35 +00002296 else if (TypeStr == "internal")
Alexis Huntdcfba7b2010-08-18 23:23:40 +00002297 type = VisibilityAttr::Hidden; // FIXME
John McCalleed64c72012-01-29 01:20:30 +00002298 else if (TypeStr == "protected") {
2299 // Complain about attempts to use protected visibility on targets
2300 // (like Darwin) that don't support it.
2301 if (!S.Context.getTargetInfo().hasProtectedVisibility()) {
2302 S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
2303 type = VisibilityAttr::Default;
2304 } else {
2305 type = VisibilityAttr::Protected;
2306 }
2307 } else {
Chris Lattnere3d20d92008-11-23 21:45:46 +00002308 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002309 return;
2310 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002311
Michael Han99315932013-01-24 16:46:58 +00002312 unsigned Index = Attr.getAttributeSpellingListIndex();
2313 VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type,
2314 Index);
Rafael Espindola19de5612013-01-12 06:42:30 +00002315 if (NewAttr)
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002316 D->addAttr(NewAttr);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002317}
2318
Chandler Carruthedc2c642011-07-02 00:01:44 +00002319static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
2320 const AttributeList &Attr) {
John McCall86bc21f2011-03-02 11:33:24 +00002321 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
2322 if (!method) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002323 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00002324 << ExpectedMethod;
John McCall86bc21f2011-03-02 11:33:24 +00002325 return;
2326 }
2327
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002328 if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
2329 if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
2330 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
John McCall86bc21f2011-03-02 11:33:24 +00002331 << "objc_method_family" << 1;
2332 } else {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002333 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
John McCall86bc21f2011-03-02 11:33:24 +00002334 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002335 Attr.setInvalid();
John McCall86bc21f2011-03-02 11:33:24 +00002336 return;
2337 }
2338
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002339 StringRef param = Attr.getParameterName()->getName();
John McCall86bc21f2011-03-02 11:33:24 +00002340 ObjCMethodFamilyAttr::FamilyKind family;
2341 if (param == "none")
2342 family = ObjCMethodFamilyAttr::OMF_None;
2343 else if (param == "alloc")
2344 family = ObjCMethodFamilyAttr::OMF_alloc;
2345 else if (param == "copy")
2346 family = ObjCMethodFamilyAttr::OMF_copy;
2347 else if (param == "init")
2348 family = ObjCMethodFamilyAttr::OMF_init;
2349 else if (param == "mutableCopy")
2350 family = ObjCMethodFamilyAttr::OMF_mutableCopy;
2351 else if (param == "new")
2352 family = ObjCMethodFamilyAttr::OMF_new;
2353 else {
2354 // Just warn and ignore it. This is future-proof against new
2355 // families being used in system headers.
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002356 S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
John McCall86bc21f2011-03-02 11:33:24 +00002357 return;
2358 }
2359
John McCall31168b02011-06-15 23:02:42 +00002360 if (family == ObjCMethodFamilyAttr::OMF_init &&
2361 !method->getResultType()->isObjCObjectPointerType()) {
2362 S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
2363 << method->getResultType();
2364 // Ignore the attribute.
2365 return;
2366 }
2367
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00002368 method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
John McCall31168b02011-06-15 23:02:42 +00002369 S.Context, family));
John McCall86bc21f2011-03-02 11:33:24 +00002370}
2371
Chandler Carruthedc2c642011-07-02 00:01:44 +00002372static void handleObjCExceptionAttr(Sema &S, Decl *D,
2373 const AttributeList &Attr) {
Chandler Carruthfcc48d92011-07-11 23:30:35 +00002374 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattner677a3582009-02-14 08:09:34 +00002375 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002376
Chris Lattner677a3582009-02-14 08:09:34 +00002377 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
2378 if (OCI == 0) {
2379 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
2380 return;
2381 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002382
Michael Han99315932013-01-24 16:46:58 +00002383 D->addAttr(::new (S.Context)
2384 ObjCExceptionAttr(Attr.getRange(), S.Context,
2385 Attr.getAttributeSpellingListIndex()));
Chris Lattner677a3582009-02-14 08:09:34 +00002386}
2387
Chandler Carruthedc2c642011-07-02 00:01:44 +00002388static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
Fariborz Jahanian255c0952009-01-13 23:34:40 +00002389 if (Attr.getNumArgs() != 0) {
John McCall61d82582010-05-28 18:25:28 +00002390 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
Fariborz Jahanian255c0952009-01-13 23:34:40 +00002391 return;
2392 }
Richard Smithdda56e42011-04-15 14:24:37 +00002393 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
Fariborz Jahanian255c0952009-01-13 23:34:40 +00002394 QualType T = TD->getUnderlyingType();
Ted Kremenek7712eef2012-08-29 22:54:47 +00002395 if (!T->isCARCBridgableType()) {
Fariborz Jahanian255c0952009-01-13 23:34:40 +00002396 S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
2397 return;
2398 }
2399 }
Fariborz Jahanianbebd0ba2012-05-31 23:18:32 +00002400 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
2401 QualType T = PD->getType();
Ted Kremenek7712eef2012-08-29 22:54:47 +00002402 if (!T->isCARCBridgableType()) {
Fariborz Jahanianbebd0ba2012-05-31 23:18:32 +00002403 S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
2404 return;
2405 }
2406 }
2407 else {
Ted Kremenek05e916b2012-03-01 01:40:32 +00002408 // It is okay to include this attribute on properties, e.g.:
2409 //
2410 // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
2411 //
2412 // In this case it follows tradition and suppresses an error in the above
2413 // case.
Fariborz Jahaniana45495a2011-11-29 01:48:40 +00002414 S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
Ted Kremenek05e916b2012-03-01 01:40:32 +00002415 }
Michael Han99315932013-01-24 16:46:58 +00002416 D->addAttr(::new (S.Context)
2417 ObjCNSObjectAttr(Attr.getRange(), S.Context,
2418 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanian255c0952009-01-13 23:34:40 +00002419}
2420
Mike Stumpd3bb5572009-07-24 19:02:52 +00002421static void
Chandler Carruthedc2c642011-07-02 00:01:44 +00002422handleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Douglas Gregor4e5cbdc2009-02-11 23:02:49 +00002423 if (Attr.getNumArgs() != 0) {
John McCall61d82582010-05-28 18:25:28 +00002424 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
Douglas Gregor4e5cbdc2009-02-11 23:02:49 +00002425 return;
2426 }
2427
2428 if (!isa<FunctionDecl>(D)) {
2429 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
2430 return;
2431 }
2432
Michael Han99315932013-01-24 16:46:58 +00002433 D->addAttr(::new (S.Context)
2434 OverloadableAttr(Attr.getRange(), S.Context,
2435 Attr.getAttributeSpellingListIndex()));
Douglas Gregor4e5cbdc2009-02-11 23:02:49 +00002436}
2437
Chandler Carruthedc2c642011-07-02 00:01:44 +00002438static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Mike Stumpd3bb5572009-07-24 19:02:52 +00002439 if (!Attr.getParameterName()) {
Chris Lattner3b054132008-11-19 05:08:23 +00002440 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00002441 << "blocks" << 1;
Steve Naroff3405a732008-09-18 16:44:58 +00002442 return;
2443 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002444
Steve Naroff3405a732008-09-18 16:44:58 +00002445 if (Attr.getNumArgs() != 0) {
Chris Lattner4bd8dd82008-11-19 08:23:25 +00002446 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
Steve Naroff3405a732008-09-18 16:44:58 +00002447 return;
2448 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002449
Alexis Huntdcfba7b2010-08-18 23:23:40 +00002450 BlocksAttr::BlockType type;
Chris Lattner68e48682008-11-20 04:42:34 +00002451 if (Attr.getParameterName()->isStr("byref"))
Steve Naroff3405a732008-09-18 16:44:58 +00002452 type = BlocksAttr::ByRef;
2453 else {
Chris Lattner3b054132008-11-19 05:08:23 +00002454 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00002455 << "blocks" << Attr.getParameterName();
Steve Naroff3405a732008-09-18 16:44:58 +00002456 return;
2457 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002458
Michael Han99315932013-01-24 16:46:58 +00002459 D->addAttr(::new (S.Context)
2460 BlocksAttr(Attr.getRange(), S.Context, type,
2461 Attr.getAttributeSpellingListIndex()));
Steve Naroff3405a732008-09-18 16:44:58 +00002462}
2463
Chandler Carruthedc2c642011-07-02 00:01:44 +00002464static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Anders Carlssonc181b012008-10-05 18:05:59 +00002465 // check the attribute arguments.
2466 if (Attr.getNumArgs() > 2) {
John McCall80ee5962011-03-02 12:15:05 +00002467 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
Anders Carlssonc181b012008-10-05 18:05:59 +00002468 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002469 }
2470
John McCallb46f2872011-09-09 07:56:05 +00002471 unsigned sentinel = 0;
Anders Carlssonc181b012008-10-05 18:05:59 +00002472 if (Attr.getNumArgs() > 0) {
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00002473 Expr *E = Attr.getArg(0);
Anders Carlssonc181b012008-10-05 18:05:59 +00002474 llvm::APSInt Idx(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00002475 if (E->isTypeDependent() || E->isValueDependent() ||
2476 !E->isIntegerConstantExpr(Idx, S.Context)) {
Chris Lattner3b054132008-11-19 05:08:23 +00002477 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00002478 << "sentinel" << 1 << E->getSourceRange();
Anders Carlssonc181b012008-10-05 18:05:59 +00002479 return;
2480 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002481
John McCallb46f2872011-09-09 07:56:05 +00002482 if (Idx.isSigned() && Idx.isNegative()) {
Chris Lattner3b054132008-11-19 05:08:23 +00002483 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2484 << E->getSourceRange();
Anders Carlssonc181b012008-10-05 18:05:59 +00002485 return;
2486 }
John McCallb46f2872011-09-09 07:56:05 +00002487
2488 sentinel = Idx.getZExtValue();
Anders Carlssonc181b012008-10-05 18:05:59 +00002489 }
2490
John McCallb46f2872011-09-09 07:56:05 +00002491 unsigned nullPos = 0;
Anders Carlssonc181b012008-10-05 18:05:59 +00002492 if (Attr.getNumArgs() > 1) {
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00002493 Expr *E = Attr.getArg(1);
Anders Carlssonc181b012008-10-05 18:05:59 +00002494 llvm::APSInt Idx(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00002495 if (E->isTypeDependent() || E->isValueDependent() ||
2496 !E->isIntegerConstantExpr(Idx, S.Context)) {
Chris Lattner3b054132008-11-19 05:08:23 +00002497 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00002498 << "sentinel" << 2 << E->getSourceRange();
Anders Carlssonc181b012008-10-05 18:05:59 +00002499 return;
2500 }
2501 nullPos = Idx.getZExtValue();
Mike Stumpd3bb5572009-07-24 19:02:52 +00002502
John McCallb46f2872011-09-09 07:56:05 +00002503 if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
Anders Carlssonc181b012008-10-05 18:05:59 +00002504 // FIXME: This error message could be improved, it would be nice
2505 // to say what the bounds actually are.
Chris Lattner3b054132008-11-19 05:08:23 +00002506 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
2507 << E->getSourceRange();
Anders Carlssonc181b012008-10-05 18:05:59 +00002508 return;
2509 }
2510 }
2511
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002512 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
John McCallb46f2872011-09-09 07:56:05 +00002513 const FunctionType *FT = FD->getType()->castAs<FunctionType>();
Chris Lattner9363e312009-03-17 23:03:47 +00002514 if (isa<FunctionNoProtoType>(FT)) {
2515 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
2516 return;
2517 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002518
Chris Lattner9363e312009-03-17 23:03:47 +00002519 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
Fariborz Jahanian6802ed92009-05-15 21:18:04 +00002520 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
Anders Carlssonc181b012008-10-05 18:05:59 +00002521 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002522 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002523 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
Anders Carlssonc181b012008-10-05 18:05:59 +00002524 if (!MD->isVariadic()) {
Fariborz Jahanian6802ed92009-05-15 21:18:04 +00002525 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
Anders Carlssonc181b012008-10-05 18:05:59 +00002526 return;
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002527 }
Eli Friedman5c5e3b72012-01-06 01:23:10 +00002528 } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
2529 if (!BD->isVariadic()) {
2530 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
2531 return;
2532 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002533 } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002534 QualType Ty = V->getType();
Fariborz Jahanian0aa5c452009-05-15 20:33:25 +00002535 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002536 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
Eric Christopherbc638a82010-12-01 22:13:54 +00002537 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002538 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
Fariborz Jahanian6802ed92009-05-15 21:18:04 +00002539 int m = Ty->isFunctionPointerType() ? 0 : 1;
2540 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002541 return;
2542 }
Mike Stump12b8ce12009-08-04 21:02:39 +00002543 } else {
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002544 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00002545 << Attr.getName() << ExpectedFunctionMethodOrBlock;
Fariborz Jahanian6607b212009-05-14 20:53:39 +00002546 return;
2547 }
Anders Carlssonc181b012008-10-05 18:05:59 +00002548 } else {
Chris Lattner3b054132008-11-19 05:08:23 +00002549 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00002550 << Attr.getName() << ExpectedFunctionMethodOrBlock;
Anders Carlssonc181b012008-10-05 18:05:59 +00002551 return;
2552 }
Michael Han99315932013-01-24 16:46:58 +00002553 D->addAttr(::new (S.Context)
2554 SentinelAttr(Attr.getRange(), S.Context, sentinel, nullPos,
2555 Attr.getAttributeSpellingListIndex()));
Anders Carlssonc181b012008-10-05 18:05:59 +00002556}
2557
Chandler Carruthedc2c642011-07-02 00:01:44 +00002558static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner237f2752009-02-14 07:37:35 +00002559 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00002560 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattner237f2752009-02-14 07:37:35 +00002561 return;
Chris Lattner237f2752009-02-14 07:37:35 +00002562
Kaelyn Uhrain8681f9d2012-11-12 23:48:05 +00002563 if (!isFunction(D) && !isa<ObjCMethodDecl>(D) && !isa<CXXRecordDecl>(D)) {
Chris Lattner237f2752009-02-14 07:37:35 +00002564 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
Kaelyn Uhrain3d699e02012-11-13 00:18:47 +00002565 << Attr.getName() << ExpectedFunctionMethodOrClass;
Chris Lattner237f2752009-02-14 07:37:35 +00002566 return;
2567 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002568
Fariborz Jahanian5cab26d2010-03-30 18:22:15 +00002569 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
2570 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2571 << Attr.getName() << 0;
Nuno Lopes56abcbd2009-12-22 23:59:52 +00002572 return;
2573 }
Fariborz Jahanian5cab26d2010-03-30 18:22:15 +00002574 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2575 if (MD->getResultType()->isVoidType()) {
2576 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2577 << Attr.getName() << 1;
2578 return;
2579 }
2580
Michael Han99315932013-01-24 16:46:58 +00002581 D->addAttr(::new (S.Context)
2582 WarnUnusedResultAttr(Attr.getRange(), S.Context,
2583 Attr.getAttributeSpellingListIndex()));
Chris Lattner237f2752009-02-14 07:37:35 +00002584}
2585
Chandler Carruthedc2c642011-07-02 00:01:44 +00002586static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002587 // check the attribute arguments.
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002588 if (Attr.hasParameterOrArguments()) {
2589 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002590 return;
2591 }
Daniel Dunbar5cb85eb2009-03-06 06:39:57 +00002592
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002593 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
Fariborz Jahanian47f9a732011-10-21 22:27:12 +00002594 if (isa<CXXRecordDecl>(D)) {
2595 D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
2596 return;
2597 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002598 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2599 << Attr.getName() << ExpectedVariableOrFunction;
Fariborz Jahanian41136ee2009-07-16 01:12:24 +00002600 return;
2601 }
2602
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002603 NamedDecl *nd = cast<NamedDecl>(D);
John McCall7a198ce2011-02-08 22:35:49 +00002604
Michael Han99315932013-01-24 16:46:58 +00002605 nd->addAttr(::new (S.Context)
2606 WeakAttr(Attr.getRange(), S.Context,
2607 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002608}
2609
Chandler Carruthedc2c642011-07-02 00:01:44 +00002610static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar5cb85eb2009-03-06 06:39:57 +00002611 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00002612 if (!checkAttributeNumArgs(S, Attr, 0))
Daniel Dunbar5cb85eb2009-03-06 06:39:57 +00002613 return;
Chandler Carruthfcc48d92011-07-11 23:30:35 +00002614
Daniel Dunbar5cb85eb2009-03-06 06:39:57 +00002615
2616 // weak_import only applies to variable & function declarations.
2617 bool isDef = false;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00002618 if (!D->canBeWeakImported(isDef)) {
2619 if (isDef)
2620 S.Diag(Attr.getLoc(),
2621 diag::warn_attribute_weak_import_invalid_on_definition)
2622 << "weak_import" << 2 /*variable and function*/;
Douglas Gregord71149a2011-03-23 13:27:51 +00002623 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
Douglas Gregore8bbc122011-09-02 00:18:52 +00002624 (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
Fariborz Jahanian3249a1e2011-10-26 23:59:12 +00002625 (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
Douglas Gregord71149a2011-03-23 13:27:51 +00002626 // Nothing to warn about here.
2627 } else
Fariborz Jahanianea70a172010-04-13 20:22:35 +00002628 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00002629 << Attr.getName() << ExpectedVariableOrFunction;
Daniel Dunbar5cb85eb2009-03-06 06:39:57 +00002630
Daniel Dunbar5cb85eb2009-03-06 06:39:57 +00002631 return;
2632 }
2633
Michael Han99315932013-01-24 16:46:58 +00002634 D->addAttr(::new (S.Context)
2635 WeakImportAttr(Attr.getRange(), S.Context,
2636 Attr.getAttributeSpellingListIndex()));
Daniel Dunbar5cb85eb2009-03-06 06:39:57 +00002637}
2638
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00002639// Handles reqd_work_group_size and work_group_size_hint.
2640static void handleWorkGroupSize(Sema &S, Decl *D,
Nick Lewyckyb9e4a3a2012-07-24 01:31:55 +00002641 const AttributeList &Attr) {
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00002642 assert(Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize
2643 || Attr.getKind() == AttributeList::AT_WorkGroupSizeHint);
2644
Nate Begemanf2758702009-06-26 06:32:41 +00002645 // Attribute has 3 arguments.
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00002646 if (!checkAttributeNumArgs(S, Attr, 3)) return;
Nate Begemanf2758702009-06-26 06:32:41 +00002647
2648 unsigned WGSize[3];
2649 for (unsigned i = 0; i < 3; ++i) {
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00002650 Expr *E = Attr.getArg(i);
Nate Begemanf2758702009-06-26 06:32:41 +00002651 llvm::APSInt ArgNum(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00002652 if (E->isTypeDependent() || E->isValueDependent() ||
2653 !E->isIntegerConstantExpr(ArgNum, S.Context)) {
Nate Begemanf2758702009-06-26 06:32:41 +00002654 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00002655 << Attr.getName()->getName() << E->getSourceRange();
Nate Begemanf2758702009-06-26 06:32:41 +00002656 return;
2657 }
2658 WGSize[i] = (unsigned) ArgNum.getZExtValue();
2659 }
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00002660
2661 if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize
2662 && D->hasAttr<ReqdWorkGroupSizeAttr>()) {
2663 ReqdWorkGroupSizeAttr *A = D->getAttr<ReqdWorkGroupSizeAttr>();
2664 if (!(A->getXDim() == WGSize[0] &&
2665 A->getYDim() == WGSize[1] &&
2666 A->getZDim() == WGSize[2])) {
2667 S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
2668 Attr.getName();
2669 }
2670 }
2671
2672 if (Attr.getKind() == AttributeList::AT_WorkGroupSizeHint
2673 && D->hasAttr<WorkGroupSizeHintAttr>()) {
2674 WorkGroupSizeHintAttr *A = D->getAttr<WorkGroupSizeHintAttr>();
2675 if (!(A->getXDim() == WGSize[0] &&
2676 A->getYDim() == WGSize[1] &&
2677 A->getZDim() == WGSize[2])) {
2678 S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
2679 Attr.getName();
2680 }
2681 }
2682
2683 if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize)
2684 D->addAttr(::new (S.Context)
2685 ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
Michael Han99315932013-01-24 16:46:58 +00002686 WGSize[0], WGSize[1], WGSize[2],
2687 Attr.getAttributeSpellingListIndex()));
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00002688 else
2689 D->addAttr(::new (S.Context)
2690 WorkGroupSizeHintAttr(Attr.getRange(), S.Context,
Michael Han99315932013-01-24 16:46:58 +00002691 WGSize[0], WGSize[1], WGSize[2],
2692 Attr.getAttributeSpellingListIndex()));
Nate Begemanf2758702009-06-26 06:32:41 +00002693}
2694
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002695SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
Michael Han99315932013-01-24 16:46:58 +00002696 StringRef Name,
2697 unsigned AttrSpellingListIndex) {
Rafael Espindola9869c3a2012-05-13 02:42:42 +00002698 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
2699 if (ExistingAttr->getName() == Name)
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002700 return NULL;
Rafael Espindola9869c3a2012-05-13 02:42:42 +00002701 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section);
2702 Diag(Range.getBegin(), diag::note_previous_attribute);
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002703 return NULL;
Rafael Espindola9869c3a2012-05-13 02:42:42 +00002704 }
Michael Han99315932013-01-24 16:46:58 +00002705 return ::new (Context) SectionAttr(Range, Context, Name,
2706 AttrSpellingListIndex);
Rafael Espindola9869c3a2012-05-13 02:42:42 +00002707}
2708
Chandler Carruthedc2c642011-07-02 00:01:44 +00002709static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar648bf782009-02-12 17:28:23 +00002710 // Attribute has no arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00002711 if (!checkAttributeNumArgs(S, Attr, 1))
Daniel Dunbar648bf782009-02-12 17:28:23 +00002712 return;
Daniel Dunbar648bf782009-02-12 17:28:23 +00002713
2714 // Make sure that there is a string literal as the sections's single
2715 // argument.
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00002716 Expr *ArgExpr = Attr.getArg(0);
Chris Lattner30ba6742009-08-10 19:03:04 +00002717 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
Daniel Dunbar648bf782009-02-12 17:28:23 +00002718 if (!SE) {
Chris Lattner30ba6742009-08-10 19:03:04 +00002719 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
Daniel Dunbar648bf782009-02-12 17:28:23 +00002720 return;
2721 }
Mike Stump11289f42009-09-09 15:08:12 +00002722
Chris Lattner30ba6742009-08-10 19:03:04 +00002723 // If the target wants to validate the section specifier, make it happen.
Douglas Gregore8bbc122011-09-02 00:18:52 +00002724 std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
Chris Lattner20aee9b2010-01-12 20:58:53 +00002725 if (!Error.empty()) {
2726 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2727 << Error;
Chris Lattner30ba6742009-08-10 19:03:04 +00002728 return;
2729 }
Mike Stump11289f42009-09-09 15:08:12 +00002730
Chris Lattner20aee9b2010-01-12 20:58:53 +00002731 // This attribute cannot be applied to local variables.
2732 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2733 S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
2734 return;
2735 }
Michael Han99315932013-01-24 16:46:58 +00002736
2737 unsigned Index = Attr.getAttributeSpellingListIndex();
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002738 SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(),
Michael Han99315932013-01-24 16:46:58 +00002739 SE->getString(), Index);
Rafael Espindolae200f1c2012-05-13 03:25:18 +00002740 if (NewAttr)
2741 D->addAttr(NewAttr);
Daniel Dunbar648bf782009-02-12 17:28:23 +00002742}
2743
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002744
Chandler Carruthedc2c642011-07-02 00:01:44 +00002745static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002746 // check the attribute arguments.
Ted Kremenek1551d552011-04-15 05:49:29 +00002747 if (Attr.hasParameterOrArguments()) {
Chris Lattner4bd8dd82008-11-19 08:23:25 +00002748 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002749 return;
2750 }
Douglas Gregor88336832011-06-15 05:45:11 +00002751
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002752 if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
Douglas Gregor88336832011-06-15 05:45:11 +00002753 if (Existing->getLocation().isInvalid())
Argyrios Kyrtzidis635a9b42011-09-13 16:05:53 +00002754 Existing->setRange(Attr.getRange());
Douglas Gregor88336832011-06-15 05:45:11 +00002755 } else {
Michael Han99315932013-01-24 16:46:58 +00002756 D->addAttr(::new (S.Context)
2757 NoThrowAttr(Attr.getRange(), S.Context,
2758 Attr.getAttributeSpellingListIndex()));
Douglas Gregor88336832011-06-15 05:45:11 +00002759 }
Chris Lattner2c6fcf52008-06-26 18:38:35 +00002760}
2761
Chandler Carruthedc2c642011-07-02 00:01:44 +00002762static void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Anders Carlssonb8316282008-10-05 23:32:53 +00002763 // check the attribute arguments.
Ted Kremenek1551d552011-04-15 05:49:29 +00002764 if (Attr.hasParameterOrArguments()) {
Chris Lattner4bd8dd82008-11-19 08:23:25 +00002765 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
Anders Carlssonb8316282008-10-05 23:32:53 +00002766 return;
2767 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002768
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002769 if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
Douglas Gregor88336832011-06-15 05:45:11 +00002770 if (Existing->getLocation().isInvalid())
Argyrios Kyrtzidis635a9b42011-09-13 16:05:53 +00002771 Existing->setRange(Attr.getRange());
Douglas Gregor88336832011-06-15 05:45:11 +00002772 } else {
Michael Han99315932013-01-24 16:46:58 +00002773 D->addAttr(::new (S.Context)
2774 ConstAttr(Attr.getRange(), S.Context,
2775 Attr.getAttributeSpellingListIndex() ));
Douglas Gregor88336832011-06-15 05:45:11 +00002776 }
Anders Carlssonb8316282008-10-05 23:32:53 +00002777}
2778
Chandler Carruthedc2c642011-07-02 00:01:44 +00002779static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Anders Carlssonb8316282008-10-05 23:32:53 +00002780 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00002781 if (!checkAttributeNumArgs(S, Attr, 0))
Anders Carlssonb8316282008-10-05 23:32:53 +00002782 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002783
Michael Han99315932013-01-24 16:46:58 +00002784 D->addAttr(::new (S.Context)
2785 PureAttr(Attr.getRange(), S.Context,
2786 Attr.getAttributeSpellingListIndex()));
Anders Carlssonb8316282008-10-05 23:32:53 +00002787}
2788
Chandler Carruthedc2c642011-07-02 00:01:44 +00002789static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Mike Stumpd3bb5572009-07-24 19:02:52 +00002790 if (!Attr.getParameterName()) {
Anders Carlssond277d792009-01-31 01:16:18 +00002791 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2792 return;
2793 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002794
Anders Carlssond277d792009-01-31 01:16:18 +00002795 if (Attr.getNumArgs() != 0) {
2796 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2797 return;
2798 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002799
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002800 VarDecl *VD = dyn_cast<VarDecl>(D);
Mike Stumpd3bb5572009-07-24 19:02:52 +00002801
Anders Carlssond277d792009-01-31 01:16:18 +00002802 if (!VD || !VD->hasLocalStorage()) {
2803 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2804 return;
2805 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002806
Anders Carlssond277d792009-01-31 01:16:18 +00002807 // Look up the function
Douglas Gregorb2ccf012010-04-15 22:33:43 +00002808 // FIXME: Lookup probably isn't looking in the right place
John McCall9f3059a2009-10-09 21:13:30 +00002809 NamedDecl *CleanupDecl
Argyrios Kyrtzidis7b608972010-12-06 17:51:50 +00002810 = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2811 Attr.getParameterLoc(), Sema::LookupOrdinaryName);
Anders Carlssond277d792009-01-31 01:16:18 +00002812 if (!CleanupDecl) {
Argyrios Kyrtzidis7b608972010-12-06 17:51:50 +00002813 S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
Anders Carlssond277d792009-01-31 01:16:18 +00002814 Attr.getParameterName();
2815 return;
2816 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002817
Anders Carlssond277d792009-01-31 01:16:18 +00002818 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2819 if (!FD) {
Argyrios Kyrtzidis7b608972010-12-06 17:51:50 +00002820 S.Diag(Attr.getParameterLoc(),
2821 diag::err_attribute_cleanup_arg_not_function)
2822 << Attr.getParameterName();
Anders Carlssond277d792009-01-31 01:16:18 +00002823 return;
2824 }
2825
Anders Carlssond277d792009-01-31 01:16:18 +00002826 if (FD->getNumParams() != 1) {
Argyrios Kyrtzidis7b608972010-12-06 17:51:50 +00002827 S.Diag(Attr.getParameterLoc(),
2828 diag::err_attribute_cleanup_func_must_take_one_arg)
2829 << Attr.getParameterName();
Anders Carlssond277d792009-01-31 01:16:18 +00002830 return;
2831 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002832
Anders Carlsson723f55d2009-02-07 23:16:50 +00002833 // We're currently more strict than GCC about what function types we accept.
2834 // If this ever proves to be a problem it should be easy to fix.
2835 QualType Ty = S.Context.getPointerType(VD->getType());
2836 QualType ParamTy = FD->getParamDecl(0)->getType();
Douglas Gregorc03a1082011-01-28 02:26:04 +00002837 if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2838 ParamTy, Ty) != Sema::Compatible) {
Argyrios Kyrtzidis7b608972010-12-06 17:51:50 +00002839 S.Diag(Attr.getParameterLoc(),
Anders Carlsson723f55d2009-02-07 23:16:50 +00002840 diag::err_attribute_cleanup_func_arg_incompatible_type) <<
2841 Attr.getParameterName() << ParamTy << Ty;
2842 return;
2843 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002844
Michael Han99315932013-01-24 16:46:58 +00002845 D->addAttr(::new (S.Context)
2846 CleanupAttr(Attr.getRange(), S.Context, FD,
2847 Attr.getAttributeSpellingListIndex()));
Eli Friedmanfa0df832012-02-02 03:46:19 +00002848 S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
Anders Carlssond277d792009-01-31 01:16:18 +00002849}
2850
Mike Stumpd3bb5572009-07-24 19:02:52 +00002851/// Handle __attribute__((format_arg((idx)))) attribute based on
Bill Wendling44426052012-12-20 19:22:21 +00002852/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Chandler Carruthedc2c642011-07-02 00:01:44 +00002853static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruthfcc48d92011-07-11 23:30:35 +00002854 if (!checkAttributeNumArgs(S, Attr, 1))
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002855 return;
Chandler Carruthfcc48d92011-07-11 23:30:35 +00002856
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002857 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002858 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00002859 << Attr.getName() << ExpectedFunction;
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002860 return;
2861 }
Chandler Carruth743682b2010-11-16 08:35:43 +00002862
2863 // In C++ the implicit 'this' function parameter also counts, and they are
2864 // counted from one.
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002865 bool HasImplicitThisParam = isInstanceMethod(D);
2866 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002867 unsigned FirstIdx = 1;
Chandler Carruth743682b2010-11-16 08:35:43 +00002868
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002869 // checks for the 2nd argument
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00002870 Expr *IdxExpr = Attr.getArg(0);
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002871 llvm::APSInt Idx(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00002872 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2873 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002874 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
2875 << "format" << 2 << IdxExpr->getSourceRange();
2876 return;
2877 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002878
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002879 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
2880 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
2881 << "format" << 2 << IdxExpr->getSourceRange();
2882 return;
2883 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00002884
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002885 unsigned ArgIdx = Idx.getZExtValue() - 1;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002886
Chandler Carruth743682b2010-11-16 08:35:43 +00002887 if (HasImplicitThisParam) {
2888 if (ArgIdx == 0) {
2889 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
2890 << "format_arg" << IdxExpr->getSourceRange();
2891 return;
2892 }
2893 ArgIdx--;
2894 }
2895
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002896 // make sure the format string is really a string
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002897 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
Mike Stumpd3bb5572009-07-24 19:02:52 +00002898
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002899 bool not_nsstring_type = !isNSStringType(Ty, S.Context);
2900 if (not_nsstring_type &&
2901 !isCFStringType(Ty, S.Context) &&
2902 (!Ty->isPointerType() ||
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002903 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002904 // FIXME: Should highlight the actual expression that has the wrong type.
2905 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
Mike Stumpd3bb5572009-07-24 19:02:52 +00002906 << (not_nsstring_type ? "a string type" : "an NSString")
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002907 << IdxExpr->getSourceRange();
2908 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002909 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002910 Ty = getFunctionOrMethodResultType(D);
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002911 if (!isNSStringType(Ty, S.Context) &&
2912 !isCFStringType(Ty, S.Context) &&
2913 (!Ty->isPointerType() ||
Ted Kremenekc23c7e62009-07-29 21:53:49 +00002914 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002915 // FIXME: Should highlight the actual expression that has the wrong type.
2916 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
Mike Stumpd3bb5572009-07-24 19:02:52 +00002917 << (not_nsstring_type ? "string type" : "NSString")
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002918 << IdxExpr->getSourceRange();
2919 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00002920 }
2921
Michael Han99315932013-01-24 16:46:58 +00002922 D->addAttr(::new (S.Context)
2923 FormatArgAttr(Attr.getRange(), S.Context, Idx.getZExtValue(),
2924 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanianf1c25022009-05-20 17:41:43 +00002925}
2926
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002927enum FormatAttrKind {
2928 CFStringFormat,
2929 NSStringFormat,
2930 StrftimeFormat,
2931 SupportedFormat,
Chris Lattner12161d32010-03-22 21:08:50 +00002932 IgnoredFormat,
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002933 InvalidFormat
2934};
2935
2936/// getFormatAttrKind - Map from format attribute names to supported format
2937/// types.
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002938static FormatAttrKind getFormatAttrKind(StringRef Format) {
Benjamin Kramer96a44b62012-05-16 12:44:25 +00002939 return llvm::StringSwitch<FormatAttrKind>(Format)
2940 // Check for formats that get handled specially.
2941 .Case("NSString", NSStringFormat)
2942 .Case("CFString", CFStringFormat)
2943 .Case("strftime", StrftimeFormat)
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002944
Benjamin Kramer96a44b62012-05-16 12:44:25 +00002945 // Otherwise, check for supported formats.
2946 .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
2947 .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
2948 .Case("kprintf", SupportedFormat) // OpenBSD.
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002949
Benjamin Kramer96a44b62012-05-16 12:44:25 +00002950 .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
2951 .Default(InvalidFormat);
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00002952}
2953
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00002954/// Handle __attribute__((init_priority(priority))) attributes based on
Bill Wendling44426052012-12-20 19:22:21 +00002955/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
Chandler Carruthedc2c642011-07-02 00:01:44 +00002956static void handleInitPriorityAttr(Sema &S, Decl *D,
2957 const AttributeList &Attr) {
David Blaikiebbafb8a2012-03-11 07:00:24 +00002958 if (!S.getLangOpts().CPlusPlus) {
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00002959 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2960 return;
2961 }
2962
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002963 if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
Fariborz Jahanian0bf5ee72010-06-18 23:14:53 +00002964 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2965 Attr.setInvalid();
2966 return;
2967 }
Chandler Carruthff4c4f02011-07-01 23:49:12 +00002968 QualType T = dyn_cast<VarDecl>(D)->getType();
Fariborz Jahanian0bf5ee72010-06-18 23:14:53 +00002969 if (S.Context.getAsArrayType(T))
2970 T = S.Context.getBaseElementType(T);
2971 if (!T->getAs<RecordType>()) {
2972 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2973 Attr.setInvalid();
2974 return;
2975 }
2976
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00002977 if (Attr.getNumArgs() != 1) {
2978 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2979 Attr.setInvalid();
2980 return;
2981 }
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00002982 Expr *priorityExpr = Attr.getArg(0);
Fariborz Jahanian0bf5ee72010-06-18 23:14:53 +00002983
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00002984 llvm::APSInt priority(32);
2985 if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
2986 !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
2987 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2988 << "init_priority" << priorityExpr->getSourceRange();
2989 Attr.setInvalid();
2990 return;
2991 }
Fariborz Jahanian9f2a4ee2010-06-21 18:45:05 +00002992 unsigned prioritynum = priority.getZExtValue();
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00002993 if (prioritynum < 101 || prioritynum > 65535) {
2994 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2995 << priorityExpr->getSourceRange();
2996 Attr.setInvalid();
2997 return;
2998 }
Michael Han99315932013-01-24 16:46:58 +00002999 D->addAttr(::new (S.Context)
3000 InitPriorityAttr(Attr.getRange(), S.Context, prioritynum,
3001 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00003002}
3003
Rafael Espindolae200f1c2012-05-13 03:25:18 +00003004FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
Michael Han99315932013-01-24 16:46:58 +00003005 int FormatIdx, int FirstArg,
3006 unsigned AttrSpellingListIndex) {
Rafael Espindola92d49452012-05-11 00:36:07 +00003007 // Check whether we already have an equivalent format attribute.
3008 for (specific_attr_iterator<FormatAttr>
3009 i = D->specific_attr_begin<FormatAttr>(),
3010 e = D->specific_attr_end<FormatAttr>();
3011 i != e ; ++i) {
3012 FormatAttr *f = *i;
3013 if (f->getType() == Format &&
3014 f->getFormatIdx() == FormatIdx &&
3015 f->getFirstArg() == FirstArg) {
3016 // If we don't have a valid location for this attribute, adopt the
3017 // location.
3018 if (f->getLocation().isInvalid())
3019 f->setRange(Range);
Rafael Espindolae200f1c2012-05-13 03:25:18 +00003020 return NULL;
Rafael Espindola92d49452012-05-11 00:36:07 +00003021 }
3022 }
3023
Michael Han99315932013-01-24 16:46:58 +00003024 return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, FirstArg,
3025 AttrSpellingListIndex);
Rafael Espindola92d49452012-05-11 00:36:07 +00003026}
3027
Mike Stumpd3bb5572009-07-24 19:02:52 +00003028/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
Bill Wendling44426052012-12-20 19:22:21 +00003029/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Chandler Carruthedc2c642011-07-02 00:01:44 +00003030static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003031
Chris Lattner4a927cb2008-06-28 23:36:30 +00003032 if (!Attr.getParameterName()) {
Chris Lattner3b054132008-11-19 05:08:23 +00003033 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00003034 << "format" << 1;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003035 return;
3036 }
3037
Chris Lattner4a927cb2008-06-28 23:36:30 +00003038 if (Attr.getNumArgs() != 2) {
Chris Lattner4bd8dd82008-11-19 08:23:25 +00003039 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003040 return;
3041 }
3042
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003043 if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
Chris Lattner3b054132008-11-19 05:08:23 +00003044 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00003045 << Attr.getName() << ExpectedFunction;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003046 return;
3047 }
3048
Chandler Carruth743682b2010-11-16 08:35:43 +00003049 // In C++ the implicit 'this' function parameter also counts, and they are
3050 // counted from one.
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003051 bool HasImplicitThisParam = isInstanceMethod(D);
3052 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003053 unsigned FirstIdx = 1;
3054
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003055 StringRef Format = Attr.getParameterName()->getName();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003056
3057 // Normalize the argument, __foo__ becomes foo.
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00003058 if (Format.startswith("__") && Format.endswith("__"))
3059 Format = Format.substr(2, Format.size() - 4);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003060
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00003061 // Check for supported formats.
3062 FormatAttrKind Kind = getFormatAttrKind(Format);
Chris Lattner12161d32010-03-22 21:08:50 +00003063
3064 if (Kind == IgnoredFormat)
3065 return;
3066
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00003067 if (Kind == InvalidFormat) {
Chris Lattner3b054132008-11-19 05:08:23 +00003068 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
Daniel Dunbar07d07852009-10-18 21:17:35 +00003069 << "format" << Attr.getParameterName()->getName();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003070 return;
3071 }
3072
3073 // checks for the 2nd argument
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00003074 Expr *IdxExpr = Attr.getArg(0);
Chris Lattnerb632a6e2008-06-29 00:43:07 +00003075 llvm::APSInt Idx(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00003076 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
3077 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
Chris Lattner3b054132008-11-19 05:08:23 +00003078 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00003079 << "format" << 2 << IdxExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003080 return;
3081 }
3082
3083 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
Chris Lattner3b054132008-11-19 05:08:23 +00003084 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00003085 << "format" << 2 << IdxExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003086 return;
3087 }
3088
3089 // FIXME: Do we need to bounds check?
3090 unsigned ArgIdx = Idx.getZExtValue() - 1;
Mike Stumpd3bb5572009-07-24 19:02:52 +00003091
Sebastian Redl6eedcc12009-11-17 18:02:24 +00003092 if (HasImplicitThisParam) {
3093 if (ArgIdx == 0) {
Chandler Carruth743682b2010-11-16 08:35:43 +00003094 S.Diag(Attr.getLoc(),
3095 diag::err_format_attribute_implicit_this_format_string)
3096 << IdxExpr->getSourceRange();
Sebastian Redl6eedcc12009-11-17 18:02:24 +00003097 return;
3098 }
3099 ArgIdx--;
3100 }
Mike Stump11289f42009-09-09 15:08:12 +00003101
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003102 // make sure the format string is really a string
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003103 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003104
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00003105 if (Kind == CFStringFormat) {
Daniel Dunbar980c6692008-09-26 03:32:58 +00003106 if (!isCFStringType(Ty, S.Context)) {
Chris Lattner3b054132008-11-19 05:08:23 +00003107 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
3108 << "a CFString" << IdxExpr->getSourceRange();
Daniel Dunbar980c6692008-09-26 03:32:58 +00003109 return;
3110 }
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00003111 } else if (Kind == NSStringFormat) {
Mike Stump87c57ac2009-05-16 07:39:55 +00003112 // FIXME: do we need to check if the type is NSString*? What are the
3113 // semantics?
Chris Lattnerb632a6e2008-06-29 00:43:07 +00003114 if (!isNSStringType(Ty, S.Context)) {
Mike Stump87c57ac2009-05-16 07:39:55 +00003115 // FIXME: Should highlight the actual expression that has the wrong type.
Chris Lattner3b054132008-11-19 05:08:23 +00003116 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
3117 << "an NSString" << IdxExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003118 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00003119 }
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003120 } else if (!Ty->isPointerType() ||
Ted Kremenekc23c7e62009-07-29 21:53:49 +00003121 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
Mike Stump87c57ac2009-05-16 07:39:55 +00003122 // FIXME: Should highlight the actual expression that has the wrong type.
Chris Lattner3b054132008-11-19 05:08:23 +00003123 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
3124 << "a string type" << IdxExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003125 return;
3126 }
3127
3128 // check the 3rd argument
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00003129 Expr *FirstArgExpr = Attr.getArg(1);
Chris Lattnerb632a6e2008-06-29 00:43:07 +00003130 llvm::APSInt FirstArg(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00003131 if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
3132 !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
Chris Lattner3b054132008-11-19 05:08:23 +00003133 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00003134 << "format" << 3 << FirstArgExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003135 return;
3136 }
3137
3138 // check if the function is variadic if the 3rd argument non-zero
3139 if (FirstArg != 0) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003140 if (isFunctionOrMethodVariadic(D)) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003141 ++NumArgs; // +1 for ...
3142 } else {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003143 S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003144 return;
3145 }
3146 }
3147
Chris Lattner4bd8dd82008-11-19 08:23:25 +00003148 // strftime requires FirstArg to be 0 because it doesn't read from any
3149 // variable the input is just the current time + the format string.
Daniel Dunbarccbd9a42009-10-18 02:09:17 +00003150 if (Kind == StrftimeFormat) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003151 if (FirstArg != 0) {
Chris Lattner3b054132008-11-19 05:08:23 +00003152 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
3153 << FirstArgExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003154 return;
3155 }
3156 // if 0 it disables parameter checking (to use with e.g. va_list)
3157 } else if (FirstArg != 0 && FirstArg != NumArgs) {
Chris Lattner3b054132008-11-19 05:08:23 +00003158 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
Chris Lattner4bd8dd82008-11-19 08:23:25 +00003159 << "format" << 3 << FirstArgExpr->getSourceRange();
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003160 return;
3161 }
3162
Rafael Espindolae200f1c2012-05-13 03:25:18 +00003163 FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format,
3164 Idx.getZExtValue(),
Michael Han99315932013-01-24 16:46:58 +00003165 FirstArg.getZExtValue(),
3166 Attr.getAttributeSpellingListIndex());
Rafael Espindolae200f1c2012-05-13 03:25:18 +00003167 if (NewAttr)
3168 D->addAttr(NewAttr);
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003169}
3170
Chandler Carruthedc2c642011-07-02 00:01:44 +00003171static void handleTransparentUnionAttr(Sema &S, Decl *D,
3172 const AttributeList &Attr) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003173 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003174 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003175 return;
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003176
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003177
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00003178 // Try to find the underlying union declaration.
3179 RecordDecl *RD = 0;
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003180 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00003181 if (TD && TD->getUnderlyingType()->isUnionType())
3182 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
3183 else
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003184 RD = dyn_cast<RecordDecl>(D);
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00003185
3186 if (!RD || !RD->isUnion()) {
Chris Lattner3b054132008-11-19 05:08:23 +00003187 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00003188 << Attr.getName() << ExpectedUnion;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003189 return;
3190 }
3191
John McCallf937c022011-10-07 06:10:15 +00003192 if (!RD->isCompleteDefinition()) {
Mike Stumpd3bb5572009-07-24 19:02:52 +00003193 S.Diag(Attr.getLoc(),
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00003194 diag::warn_transparent_union_attribute_not_definition);
3195 return;
3196 }
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003197
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +00003198 RecordDecl::field_iterator Field = RD->field_begin(),
3199 FieldEnd = RD->field_end();
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00003200 if (Field == FieldEnd) {
3201 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
3202 return;
3203 }
Eli Friedman7c9ba6a2008-09-02 05:19:23 +00003204
David Blaikie40ed2972012-06-06 20:45:41 +00003205 FieldDecl *FirstField = *Field;
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00003206 QualType FirstType = FirstField->getType();
Douglas Gregor21872662010-06-30 17:24:13 +00003207 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
Mike Stumpd3bb5572009-07-24 19:02:52 +00003208 S.Diag(FirstField->getLocation(),
Douglas Gregor21872662010-06-30 17:24:13 +00003209 diag::warn_transparent_union_attribute_floating)
3210 << FirstType->isVectorType() << FirstType;
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00003211 return;
3212 }
3213
3214 uint64_t FirstSize = S.Context.getTypeSize(FirstType);
3215 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
3216 for (; Field != FieldEnd; ++Field) {
3217 QualType FieldType = Field->getType();
3218 if (S.Context.getTypeSize(FieldType) != FirstSize ||
3219 S.Context.getTypeAlign(FieldType) != FirstAlign) {
3220 // Warn if we drop the attribute.
3221 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
Mike Stumpd3bb5572009-07-24 19:02:52 +00003222 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00003223 : S.Context.getTypeAlign(FieldType);
Mike Stumpd3bb5572009-07-24 19:02:52 +00003224 S.Diag(Field->getLocation(),
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00003225 diag::warn_transparent_union_attribute_field_size_align)
3226 << isSize << Field->getDeclName() << FieldBits;
3227 unsigned FirstBits = isSize? FirstSize : FirstAlign;
Mike Stumpd3bb5572009-07-24 19:02:52 +00003228 S.Diag(FirstField->getLocation(),
Douglas Gregor0cfbdab2009-04-29 22:16:16 +00003229 diag::note_transparent_union_first_field_size_align)
3230 << isSize << FirstBits;
Eli Friedman7c9ba6a2008-09-02 05:19:23 +00003231 return;
3232 }
3233 }
3234
Michael Han99315932013-01-24 16:46:58 +00003235 RD->addAttr(::new (S.Context)
3236 TransparentUnionAttr(Attr.getRange(), S.Context,
3237 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003238}
3239
Chandler Carruthedc2c642011-07-02 00:01:44 +00003240static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003241 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003242 if (!checkAttributeNumArgs(S, Attr, 1))
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003243 return;
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003244
Peter Collingbournee57e9ef2010-11-23 20:45:58 +00003245 Expr *ArgExpr = Attr.getArg(0);
Chris Lattner30ba6742009-08-10 19:03:04 +00003246 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
Mike Stumpd3bb5572009-07-24 19:02:52 +00003247
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003248 // Make sure that there is a string literal as the annotation's single
3249 // argument.
3250 if (!SE) {
Chris Lattner30ba6742009-08-10 19:03:04 +00003251 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003252 return;
3253 }
Julien Lerouge5a6b6982011-09-09 22:41:49 +00003254
3255 // Don't duplicate annotations that are already set.
3256 for (specific_attr_iterator<AnnotateAttr>
3257 i = D->specific_attr_begin<AnnotateAttr>(),
3258 e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
3259 if ((*i)->getAnnotation() == SE->getString())
3260 return;
3261 }
Michael Han99315932013-01-24 16:46:58 +00003262
3263 D->addAttr(::new (S.Context)
3264 AnnotateAttr(Attr.getRange(), S.Context, SE->getString(),
3265 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003266}
3267
Chandler Carruthedc2c642011-07-02 00:01:44 +00003268static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003269 // check the attribute arguments.
Chris Lattner4a927cb2008-06-28 23:36:30 +00003270 if (Attr.getNumArgs() > 1) {
Chris Lattner4bd8dd82008-11-19 08:23:25 +00003271 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003272 return;
3273 }
Aaron Ballman478faed2012-06-19 22:09:27 +00003274
Alexis Hunt96d5c762009-11-21 08:43:09 +00003275 //FIXME: The C++0x version of this attribute has more limited applicabilty
3276 // than GNU's, and should error out when it is used to specify a
3277 // weaker alignment, rather than being silently ignored.
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003278
Chris Lattner4a927cb2008-06-28 23:36:30 +00003279 if (Attr.getNumArgs() == 0) {
Aaron Ballman478faed2012-06-19 22:09:27 +00003280 D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
Michael Han99315932013-01-24 16:46:58 +00003281 true, 0, Attr.isDeclspecAttribute(),
3282 Attr.getAttributeSpellingListIndex()));
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003283 return;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003284 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00003285
Aaron Ballman478faed2012-06-19 22:09:27 +00003286 S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0),
Michael Han99315932013-01-24 16:46:58 +00003287 Attr.isDeclspecAttribute(),
3288 Attr.getAttributeSpellingListIndex());
Chandler Carruthf40c42f2010-06-25 03:22:07 +00003289}
3290
Aaron Ballman478faed2012-06-19 22:09:27 +00003291void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
Michael Han99315932013-01-24 16:46:58 +00003292 bool isDeclSpec, unsigned SpellingListIndex) {
Peter Collingbourne7d33cd32011-10-23 20:07:52 +00003293 // FIXME: Handle pack-expansions here.
3294 if (DiagnoseUnexpandedParameterPack(E))
3295 return;
3296
Chandler Carruthf40c42f2010-06-25 03:22:07 +00003297 if (E->isTypeDependent() || E->isValueDependent()) {
3298 // Save dependent expressions in the AST to be instantiated.
Aaron Ballman478faed2012-06-19 22:09:27 +00003299 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E,
Michael Han99315932013-01-24 16:46:58 +00003300 isDeclSpec, SpellingListIndex));
Chandler Carruthf40c42f2010-06-25 03:22:07 +00003301 return;
3302 }
Aaron Ballman478faed2012-06-19 22:09:27 +00003303
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00003304 SourceLocation AttrLoc = AttrRange.getBegin();
Alexis Huntdcfba7b2010-08-18 23:23:40 +00003305 // FIXME: Cache the number on the Attr object?
Chris Lattner4627b742008-06-28 23:50:44 +00003306 llvm::APSInt Alignment(32);
Douglas Gregore2b37442012-05-04 22:38:52 +00003307 ExprResult ICE
3308 = VerifyIntegerConstantExpression(E, &Alignment,
3309 diag::err_aligned_attribute_argument_not_int,
3310 /*AllowFold*/ false);
Richard Smithf4c51d92012-02-04 09:53:13 +00003311 if (ICE.isInvalid())
Chris Lattner4627b742008-06-28 23:50:44 +00003312 return;
Daniel Dunbar6e8c07d2009-02-16 23:37:57 +00003313 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
Chandler Carruthf40c42f2010-06-25 03:22:07 +00003314 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
3315 << E->getSourceRange();
Daniel Dunbar6e8c07d2009-02-16 23:37:57 +00003316 return;
3317 }
Aaron Ballman478faed2012-06-19 22:09:27 +00003318 if (isDeclSpec) {
3319 // We've already verified it's a power of 2, now let's make sure it's
3320 // 8192 or less.
3321 if (Alignment.getZExtValue() > 8192) {
3322 Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192)
3323 << E->getSourceRange();
3324 return;
3325 }
3326 }
Daniel Dunbar6e8c07d2009-02-16 23:37:57 +00003327
Aaron Ballman478faed2012-06-19 22:09:27 +00003328 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take(),
Michael Han99315932013-01-24 16:46:58 +00003329 isDeclSpec, SpellingListIndex));
Alexis Huntdcfba7b2010-08-18 23:23:40 +00003330}
3331
Aaron Ballman478faed2012-06-19 22:09:27 +00003332void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
Richard Smitha5aaca92013-01-29 04:21:28 +00003333 bool isDeclSpec, unsigned SpellingListIndex) {
Alexis Huntdcfba7b2010-08-18 23:23:40 +00003334 // FIXME: Cache the number on the Attr object if non-dependent?
3335 // FIXME: Perform checking of type validity
Aaron Ballman478faed2012-06-19 22:09:27 +00003336 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS,
Richard Smitha5aaca92013-01-29 04:21:28 +00003337 isDeclSpec, SpellingListIndex));
Alexis Huntdcfba7b2010-08-18 23:23:40 +00003338 return;
Chris Lattner2c6fcf52008-06-26 18:38:35 +00003339}
Chris Lattneracbc2d22008-06-27 22:18:37 +00003340
Chandler Carruth3ed22c32011-07-01 23:49:16 +00003341/// handleModeAttr - This attribute modifies the width of a decl with primitive
Mike Stumpd3bb5572009-07-24 19:02:52 +00003342/// type.
Chris Lattneracbc2d22008-06-27 22:18:37 +00003343///
Mike Stumpd3bb5572009-07-24 19:02:52 +00003344/// Despite what would be logical, the mode attribute is a decl attribute, not a
3345/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
3346/// HImode, not an intermediate pointer.
Chandler Carruthedc2c642011-07-02 00:01:44 +00003347static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattneracbc2d22008-06-27 22:18:37 +00003348 // This attribute isn't documented, but glibc uses it. It changes
3349 // the width of an int or unsigned int to the specified size.
3350
3351 // Check that there aren't any arguments
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003352 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattneracbc2d22008-06-27 22:18:37 +00003353 return;
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003354
Chris Lattneracbc2d22008-06-27 22:18:37 +00003355
3356 IdentifierInfo *Name = Attr.getParameterName();
3357 if (!Name) {
Chris Lattnera663a0a2008-06-29 00:28:59 +00003358 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
Chris Lattneracbc2d22008-06-27 22:18:37 +00003359 return;
3360 }
Daniel Dunbarafff4342009-10-18 02:09:24 +00003361
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003362 StringRef Str = Attr.getParameterName()->getName();
Chris Lattneracbc2d22008-06-27 22:18:37 +00003363
3364 // Normalize the attribute name, __foo__ becomes foo.
Daniel Dunbarafff4342009-10-18 02:09:24 +00003365 if (Str.startswith("__") && Str.endswith("__"))
3366 Str = Str.substr(2, Str.size() - 4);
Chris Lattneracbc2d22008-06-27 22:18:37 +00003367
3368 unsigned DestWidth = 0;
3369 bool IntegerMode = true;
Eli Friedman4735374e2009-03-03 06:41:03 +00003370 bool ComplexMode = false;
Daniel Dunbarafff4342009-10-18 02:09:24 +00003371 switch (Str.size()) {
Chris Lattneracbc2d22008-06-27 22:18:37 +00003372 case 2:
Eli Friedman4735374e2009-03-03 06:41:03 +00003373 switch (Str[0]) {
3374 case 'Q': DestWidth = 8; break;
3375 case 'H': DestWidth = 16; break;
3376 case 'S': DestWidth = 32; break;
3377 case 'D': DestWidth = 64; break;
3378 case 'X': DestWidth = 96; break;
3379 case 'T': DestWidth = 128; break;
3380 }
3381 if (Str[1] == 'F') {
3382 IntegerMode = false;
3383 } else if (Str[1] == 'C') {
3384 IntegerMode = false;
3385 ComplexMode = true;
3386 } else if (Str[1] != 'I') {
3387 DestWidth = 0;
3388 }
Chris Lattneracbc2d22008-06-27 22:18:37 +00003389 break;
3390 case 4:
3391 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
3392 // pointer on PIC16 and other embedded platforms.
Daniel Dunbarafff4342009-10-18 02:09:24 +00003393 if (Str == "word")
Douglas Gregore8bbc122011-09-02 00:18:52 +00003394 DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
Daniel Dunbarafff4342009-10-18 02:09:24 +00003395 else if (Str == "byte")
Douglas Gregore8bbc122011-09-02 00:18:52 +00003396 DestWidth = S.Context.getTargetInfo().getCharWidth();
Chris Lattneracbc2d22008-06-27 22:18:37 +00003397 break;
3398 case 7:
Daniel Dunbarafff4342009-10-18 02:09:24 +00003399 if (Str == "pointer")
Douglas Gregore8bbc122011-09-02 00:18:52 +00003400 DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
Chris Lattneracbc2d22008-06-27 22:18:37 +00003401 break;
Rafael Espindolaf0dafd32013-01-07 19:58:54 +00003402 case 11:
3403 if (Str == "unwind_word")
Rafael Espindola03705972013-01-07 20:01:57 +00003404 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
Rafael Espindolaf0dafd32013-01-07 19:58:54 +00003405 break;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003406 }
3407
3408 QualType OldTy;
Richard Smithdda56e42011-04-15 14:24:37 +00003409 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
Chris Lattneracbc2d22008-06-27 22:18:37 +00003410 OldTy = TD->getUnderlyingType();
3411 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
3412 OldTy = VD->getType();
3413 else {
Chris Lattner3b054132008-11-19 05:08:23 +00003414 S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00003415 << "mode" << Attr.getRange();
Chris Lattneracbc2d22008-06-27 22:18:37 +00003416 return;
3417 }
Eli Friedman4735374e2009-03-03 06:41:03 +00003418
John McCall9dd450b2009-09-21 23:43:11 +00003419 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
Eli Friedman4735374e2009-03-03 06:41:03 +00003420 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
3421 else if (IntegerMode) {
Douglas Gregorb90df602010-06-16 00:17:44 +00003422 if (!OldTy->isIntegralOrEnumerationType())
Eli Friedman4735374e2009-03-03 06:41:03 +00003423 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3424 } else if (ComplexMode) {
3425 if (!OldTy->isComplexType())
3426 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3427 } else {
3428 if (!OldTy->isFloatingType())
3429 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3430 }
3431
Mike Stump87c57ac2009-05-16 07:39:55 +00003432 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
3433 // and friends, at least with glibc.
3434 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
3435 // width on unusual platforms.
Eli Friedman1efaaea2009-02-13 02:31:07 +00003436 // FIXME: Make sure floating-point mappings are accurate
3437 // FIXME: Support XF and TF types
Chris Lattneracbc2d22008-06-27 22:18:37 +00003438 QualType NewTy;
3439 switch (DestWidth) {
3440 case 0:
Chris Lattner4bd8dd82008-11-19 08:23:25 +00003441 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003442 return;
3443 default:
Chris Lattner4bd8dd82008-11-19 08:23:25 +00003444 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003445 return;
3446 case 8:
Eli Friedman4735374e2009-03-03 06:41:03 +00003447 if (!IntegerMode) {
3448 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3449 return;
3450 }
Chris Lattneracbc2d22008-06-27 22:18:37 +00003451 if (OldTy->isSignedIntegerType())
Chris Lattnera663a0a2008-06-29 00:28:59 +00003452 NewTy = S.Context.SignedCharTy;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003453 else
Chris Lattnera663a0a2008-06-29 00:28:59 +00003454 NewTy = S.Context.UnsignedCharTy;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003455 break;
3456 case 16:
Eli Friedman4735374e2009-03-03 06:41:03 +00003457 if (!IntegerMode) {
3458 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3459 return;
3460 }
Chris Lattneracbc2d22008-06-27 22:18:37 +00003461 if (OldTy->isSignedIntegerType())
Chris Lattnera663a0a2008-06-29 00:28:59 +00003462 NewTy = S.Context.ShortTy;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003463 else
Chris Lattnera663a0a2008-06-29 00:28:59 +00003464 NewTy = S.Context.UnsignedShortTy;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003465 break;
3466 case 32:
3467 if (!IntegerMode)
Chris Lattnera663a0a2008-06-29 00:28:59 +00003468 NewTy = S.Context.FloatTy;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003469 else if (OldTy->isSignedIntegerType())
Chris Lattnera663a0a2008-06-29 00:28:59 +00003470 NewTy = S.Context.IntTy;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003471 else
Chris Lattnera663a0a2008-06-29 00:28:59 +00003472 NewTy = S.Context.UnsignedIntTy;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003473 break;
3474 case 64:
3475 if (!IntegerMode)
Chris Lattnera663a0a2008-06-29 00:28:59 +00003476 NewTy = S.Context.DoubleTy;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003477 else if (OldTy->isSignedIntegerType())
Douglas Gregore8bbc122011-09-02 00:18:52 +00003478 if (S.Context.getTargetInfo().getLongWidth() == 64)
Chandler Carruth72343702010-01-26 06:39:24 +00003479 NewTy = S.Context.LongTy;
3480 else
3481 NewTy = S.Context.LongLongTy;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003482 else
Douglas Gregore8bbc122011-09-02 00:18:52 +00003483 if (S.Context.getTargetInfo().getLongWidth() == 64)
Chandler Carruth72343702010-01-26 06:39:24 +00003484 NewTy = S.Context.UnsignedLongTy;
3485 else
3486 NewTy = S.Context.UnsignedLongLongTy;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003487 break;
Eli Friedman4735374e2009-03-03 06:41:03 +00003488 case 96:
3489 NewTy = S.Context.LongDoubleTy;
3490 break;
Eli Friedman1efaaea2009-02-13 02:31:07 +00003491 case 128:
3492 if (!IntegerMode) {
3493 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3494 return;
3495 }
Anders Carlsson88ea2452009-12-29 07:07:36 +00003496 if (OldTy->isSignedIntegerType())
3497 NewTy = S.Context.Int128Ty;
3498 else
3499 NewTy = S.Context.UnsignedInt128Ty;
Eli Friedman4735374e2009-03-03 06:41:03 +00003500 break;
Chris Lattneracbc2d22008-06-27 22:18:37 +00003501 }
3502
Eli Friedman4735374e2009-03-03 06:41:03 +00003503 if (ComplexMode) {
3504 NewTy = S.Context.getComplexType(NewTy);
Chris Lattneracbc2d22008-06-27 22:18:37 +00003505 }
3506
3507 // Install the new type.
Richard Smithdda56e42011-04-15 14:24:37 +00003508 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
John McCall703a3f82009-10-24 08:00:42 +00003509 // FIXME: preserve existing source info.
John McCallbcd03502009-12-07 02:54:59 +00003510 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
John McCall703a3f82009-10-24 08:00:42 +00003511 } else
Chris Lattneracbc2d22008-06-27 22:18:37 +00003512 cast<ValueDecl>(D)->setType(NewTy);
3513}
Chris Lattner9e2aafe2008-06-29 00:23:49 +00003514
Chandler Carruthedc2c642011-07-02 00:01:44 +00003515static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Anders Carlsson76187b42009-02-13 06:46:13 +00003516 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003517 if (!checkAttributeNumArgs(S, Attr, 0))
Anders Carlsson76187b42009-02-13 06:46:13 +00003518 return;
Anders Carlsson63784f42009-02-13 08:11:52 +00003519
Nick Lewycky08597072012-07-24 01:40:49 +00003520 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
3521 if (!VD->hasGlobalStorage())
3522 S.Diag(Attr.getLoc(),
3523 diag::warn_attribute_requires_functions_or_static_globals)
3524 << Attr.getName();
3525 } else if (!isFunctionOrMethod(D)) {
3526 S.Diag(Attr.getLoc(),
3527 diag::warn_attribute_requires_functions_or_static_globals)
3528 << Attr.getName();
Anders Carlsson76187b42009-02-13 06:46:13 +00003529 return;
3530 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00003531
Michael Han99315932013-01-24 16:46:58 +00003532 D->addAttr(::new (S.Context)
3533 NoDebugAttr(Attr.getRange(), S.Context,
3534 Attr.getAttributeSpellingListIndex()));
Anders Carlsson76187b42009-02-13 06:46:13 +00003535}
3536
Chandler Carruthedc2c642011-07-02 00:01:44 +00003537static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Anders Carlsson88097122009-02-19 19:16:48 +00003538 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003539 if (!checkAttributeNumArgs(S, Attr, 0))
Anders Carlsson88097122009-02-19 19:16:48 +00003540 return;
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003541
Mike Stumpd3bb5572009-07-24 19:02:52 +00003542
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003543 if (!isa<FunctionDecl>(D)) {
Anders Carlsson88097122009-02-19 19:16:48 +00003544 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00003545 << Attr.getName() << ExpectedFunction;
Anders Carlsson88097122009-02-19 19:16:48 +00003546 return;
3547 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00003548
Michael Han99315932013-01-24 16:46:58 +00003549 D->addAttr(::new (S.Context)
3550 NoInlineAttr(Attr.getRange(), S.Context,
3551 Attr.getAttributeSpellingListIndex()));
Anders Carlsson88097122009-02-19 19:16:48 +00003552}
3553
Chandler Carruthedc2c642011-07-02 00:01:44 +00003554static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
3555 const AttributeList &Attr) {
Chris Lattner3c77a352010-06-22 00:03:40 +00003556 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003557 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattner3c77a352010-06-22 00:03:40 +00003558 return;
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003559
Chris Lattner3c77a352010-06-22 00:03:40 +00003560
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003561 if (!isa<FunctionDecl>(D)) {
Chris Lattner3c77a352010-06-22 00:03:40 +00003562 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00003563 << Attr.getName() << ExpectedFunction;
Chris Lattner3c77a352010-06-22 00:03:40 +00003564 return;
3565 }
3566
Michael Han99315932013-01-24 16:46:58 +00003567 D->addAttr(::new (S.Context)
3568 NoInstrumentFunctionAttr(Attr.getRange(), S.Context,
3569 Attr.getAttributeSpellingListIndex()));
Chris Lattner3c77a352010-06-22 00:03:40 +00003570}
3571
Chandler Carruthedc2c642011-07-02 00:01:44 +00003572static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003573 if (S.LangOpts.CUDA) {
3574 // check the attribute arguments.
Ted Kremenek1551d552011-04-15 05:49:29 +00003575 if (Attr.hasParameterOrArguments()) {
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003576 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3577 return;
3578 }
3579
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003580 if (!isa<VarDecl>(D)) {
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003581 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00003582 << Attr.getName() << ExpectedVariable;
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003583 return;
3584 }
3585
Michael Han99315932013-01-24 16:46:58 +00003586 D->addAttr(::new (S.Context)
3587 CUDAConstantAttr(Attr.getRange(), S.Context,
3588 Attr.getAttributeSpellingListIndex()));
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003589 } else {
3590 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
3591 }
3592}
3593
Chandler Carruthedc2c642011-07-02 00:01:44 +00003594static void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003595 if (S.LangOpts.CUDA) {
3596 // check the attribute arguments.
3597 if (Attr.getNumArgs() != 0) {
3598 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3599 return;
3600 }
3601
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003602 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003603 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00003604 << Attr.getName() << ExpectedVariableOrFunction;
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003605 return;
3606 }
3607
Michael Han99315932013-01-24 16:46:58 +00003608 D->addAttr(::new (S.Context)
3609 CUDADeviceAttr(Attr.getRange(), S.Context,
3610 Attr.getAttributeSpellingListIndex()));
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003611 } else {
3612 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
3613 }
3614}
3615
Chandler Carruthedc2c642011-07-02 00:01:44 +00003616static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003617 if (S.LangOpts.CUDA) {
3618 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003619 if (!checkAttributeNumArgs(S, Attr, 0))
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003620 return;
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003621
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003622 if (!isa<FunctionDecl>(D)) {
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003623 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00003624 << Attr.getName() << ExpectedFunction;
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003625 return;
3626 }
3627
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003628 FunctionDecl *FD = cast<FunctionDecl>(D);
Peter Collingbournee8cfaf42010-12-12 23:02:57 +00003629 if (!FD->getResultType()->isVoidType()) {
Abramo Bagnara6d810632010-12-14 22:11:44 +00003630 TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
Peter Collingbournee8cfaf42010-12-12 23:02:57 +00003631 if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
3632 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
3633 << FD->getType()
3634 << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
3635 "void");
3636 } else {
3637 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
3638 << FD->getType();
3639 }
3640 return;
3641 }
3642
Michael Han99315932013-01-24 16:46:58 +00003643 D->addAttr(::new (S.Context)
3644 CUDAGlobalAttr(Attr.getRange(), S.Context,
3645 Attr.getAttributeSpellingListIndex()));
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003646 } else {
3647 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
3648 }
3649}
3650
Chandler Carruthedc2c642011-07-02 00:01:44 +00003651static void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003652 if (S.LangOpts.CUDA) {
3653 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003654 if (!checkAttributeNumArgs(S, Attr, 0))
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003655 return;
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003656
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003657
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003658 if (!isa<FunctionDecl>(D)) {
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003659 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00003660 << Attr.getName() << ExpectedFunction;
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003661 return;
3662 }
3663
Michael Han99315932013-01-24 16:46:58 +00003664 D->addAttr(::new (S.Context)
3665 CUDAHostAttr(Attr.getRange(), S.Context,
3666 Attr.getAttributeSpellingListIndex()));
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003667 } else {
3668 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
3669 }
3670}
3671
Chandler Carruthedc2c642011-07-02 00:01:44 +00003672static void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003673 if (S.LangOpts.CUDA) {
3674 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003675 if (!checkAttributeNumArgs(S, Attr, 0))
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003676 return;
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003677
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003678 if (!isa<VarDecl>(D)) {
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003679 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00003680 << Attr.getName() << ExpectedVariable;
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003681 return;
3682 }
3683
Michael Han99315932013-01-24 16:46:58 +00003684 D->addAttr(::new (S.Context)
3685 CUDASharedAttr(Attr.getRange(), S.Context,
3686 Attr.getAttributeSpellingListIndex()));
Peter Collingbourne6ab610c2010-12-01 03:15:31 +00003687 } else {
3688 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
3689 }
3690}
3691
Chandler Carruthedc2c642011-07-02 00:01:44 +00003692static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattnereaad6b72009-04-14 16:30:50 +00003693 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00003694 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattnereaad6b72009-04-14 16:30:50 +00003695 return;
Mike Stumpd3bb5572009-07-24 19:02:52 +00003696
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003697 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
Chris Lattner4225e232009-04-14 17:02:11 +00003698 if (Fn == 0) {
Chris Lattnereaad6b72009-04-14 16:30:50 +00003699 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00003700 << Attr.getName() << ExpectedFunction;
Chris Lattnereaad6b72009-04-14 16:30:50 +00003701 return;
3702 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00003703
Douglas Gregor35b57532009-10-27 21:01:01 +00003704 if (!Fn->isInlineSpecified()) {
Chris Lattnerddf6ca02009-04-20 19:12:28 +00003705 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
Chris Lattner4225e232009-04-14 17:02:11 +00003706 return;
3707 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00003708
Michael Han99315932013-01-24 16:46:58 +00003709 D->addAttr(::new (S.Context)
3710 GNUInlineAttr(Attr.getRange(), S.Context,
3711 Attr.getAttributeSpellingListIndex()));
Chris Lattnereaad6b72009-04-14 16:30:50 +00003712}
3713
Chandler Carruthedc2c642011-07-02 00:01:44 +00003714static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003715 if (hasDeclarator(D)) return;
Abramo Bagnara50099372010-04-30 13:10:51 +00003716
Aaron Ballman02df2e02012-12-09 17:45:41 +00003717 const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003718 // Diagnostic is emitted elsewhere: here we store the (valid) Attr
John McCall3882ace2011-01-05 12:14:39 +00003719 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
3720 CallingConv CC;
Aaron Ballman02df2e02012-12-09 17:45:41 +00003721 if (S.CheckCallingConvAttr(Attr, CC, FD))
John McCall3882ace2011-01-05 12:14:39 +00003722 return;
3723
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003724 if (!isa<ObjCMethodDecl>(D)) {
3725 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3726 << Attr.getName() << ExpectedFunctionOrMethod;
John McCall3882ace2011-01-05 12:14:39 +00003727 return;
3728 }
3729
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003730 switch (Attr.getKind()) {
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003731 case AttributeList::AT_FastCall:
Michael Han99315932013-01-24 16:46:58 +00003732 D->addAttr(::new (S.Context)
3733 FastCallAttr(Attr.getRange(), S.Context,
3734 Attr.getAttributeSpellingListIndex()));
Abramo Bagnara50099372010-04-30 13:10:51 +00003735 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003736 case AttributeList::AT_StdCall:
Michael Han99315932013-01-24 16:46:58 +00003737 D->addAttr(::new (S.Context)
3738 StdCallAttr(Attr.getRange(), S.Context,
3739 Attr.getAttributeSpellingListIndex()));
Abramo Bagnara50099372010-04-30 13:10:51 +00003740 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003741 case AttributeList::AT_ThisCall:
Michael Han99315932013-01-24 16:46:58 +00003742 D->addAttr(::new (S.Context)
3743 ThisCallAttr(Attr.getRange(), S.Context,
3744 Attr.getAttributeSpellingListIndex()));
Douglas Gregor4d13d102010-08-30 23:30:49 +00003745 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003746 case AttributeList::AT_CDecl:
Michael Han99315932013-01-24 16:46:58 +00003747 D->addAttr(::new (S.Context)
3748 CDeclAttr(Attr.getRange(), S.Context,
3749 Attr.getAttributeSpellingListIndex()));
Abramo Bagnara50099372010-04-30 13:10:51 +00003750 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003751 case AttributeList::AT_Pascal:
Michael Han99315932013-01-24 16:46:58 +00003752 D->addAttr(::new (S.Context)
3753 PascalAttr(Attr.getRange(), S.Context,
3754 Attr.getAttributeSpellingListIndex()));
Dawn Perchik335e16b2010-09-03 01:29:35 +00003755 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003756 case AttributeList::AT_Pcs: {
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003757 PcsAttr::PCSType PCS;
Benjamin Kramer25885f42012-08-14 13:24:39 +00003758 switch (CC) {
3759 case CC_AAPCS:
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003760 PCS = PcsAttr::AAPCS;
Benjamin Kramer25885f42012-08-14 13:24:39 +00003761 break;
3762 case CC_AAPCS_VFP:
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003763 PCS = PcsAttr::AAPCS_VFP;
Benjamin Kramer25885f42012-08-14 13:24:39 +00003764 break;
3765 default:
3766 llvm_unreachable("unexpected calling convention in pcs attribute");
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003767 }
3768
Michael Han99315932013-01-24 16:46:58 +00003769 D->addAttr(::new (S.Context)
3770 PcsAttr(Attr.getRange(), S.Context, PCS,
3771 Attr.getAttributeSpellingListIndex()));
Derek Schuffa2020962012-10-16 22:30:41 +00003772 return;
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003773 }
Derek Schuffa2020962012-10-16 22:30:41 +00003774 case AttributeList::AT_PnaclCall:
Michael Han99315932013-01-24 16:46:58 +00003775 D->addAttr(::new (S.Context)
3776 PnaclCallAttr(Attr.getRange(), S.Context,
3777 Attr.getAttributeSpellingListIndex()));
Derek Schuffa2020962012-10-16 22:30:41 +00003778 return;
Guy Benyeif0a014b2012-12-25 08:53:55 +00003779 case AttributeList::AT_IntelOclBicc:
Michael Han99315932013-01-24 16:46:58 +00003780 D->addAttr(::new (S.Context)
3781 IntelOclBiccAttr(Attr.getRange(), S.Context,
3782 Attr.getAttributeSpellingListIndex()));
Guy Benyeif0a014b2012-12-25 08:53:55 +00003783 return;
Derek Schuffa2020962012-10-16 22:30:41 +00003784
Abramo Bagnara50099372010-04-30 13:10:51 +00003785 default:
3786 llvm_unreachable("unexpected attribute kind");
Abramo Bagnara50099372010-04-30 13:10:51 +00003787 }
3788}
3789
Chandler Carruthedc2c642011-07-02 00:01:44 +00003790static void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
Chandler Carruth9312c642011-07-11 23:33:05 +00003791 assert(!Attr.isInvalid());
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00003792 D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
Peter Collingbourne7ce13fc2011-02-14 01:42:53 +00003793}
3794
Aaron Ballman02df2e02012-12-09 17:45:41 +00003795bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
3796 const FunctionDecl *FD) {
John McCall3882ace2011-01-05 12:14:39 +00003797 if (attr.isInvalid())
3798 return true;
3799
Benjamin Kramer833fb9f2012-08-14 13:13:47 +00003800 unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0;
3801 if (attr.getNumArgs() != ReqArgs || attr.getParameterName()) {
3802 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << ReqArgs;
John McCall3882ace2011-01-05 12:14:39 +00003803 attr.setInvalid();
3804 return true;
3805 }
3806
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003807 // TODO: diagnose uses of these conventions on the wrong target. Or, better
3808 // move to TargetAttributesSema one day.
John McCall3882ace2011-01-05 12:14:39 +00003809 switch (attr.getKind()) {
Alexis Hunt3bc72c12012-06-19 23:57:03 +00003810 case AttributeList::AT_CDecl: CC = CC_C; break;
3811 case AttributeList::AT_FastCall: CC = CC_X86FastCall; break;
3812 case AttributeList::AT_StdCall: CC = CC_X86StdCall; break;
3813 case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break;
3814 case AttributeList::AT_Pascal: CC = CC_X86Pascal; break;
3815 case AttributeList::AT_Pcs: {
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003816 Expr *Arg = attr.getArg(0);
3817 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
Douglas Gregorfb65e592011-07-27 05:40:30 +00003818 if (!Str || !Str->isAscii()) {
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003819 Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3820 << "pcs" << 1;
3821 attr.setInvalid();
3822 return true;
3823 }
3824
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003825 StringRef StrRef = Str->getString();
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003826 if (StrRef == "aapcs") {
3827 CC = CC_AAPCS;
3828 break;
3829 } else if (StrRef == "aapcs-vfp") {
3830 CC = CC_AAPCS_VFP;
3831 break;
3832 }
Benjamin Kramer833fb9f2012-08-14 13:13:47 +00003833
3834 attr.setInvalid();
3835 Diag(attr.getLoc(), diag::err_invalid_pcs);
3836 return true;
Anton Korobeynikov231e8752011-04-14 20:06:49 +00003837 }
Derek Schuffa2020962012-10-16 22:30:41 +00003838 case AttributeList::AT_PnaclCall: CC = CC_PnaclCall; break;
Guy Benyeif0a014b2012-12-25 08:53:55 +00003839 case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break;
David Blaikie8a40f702012-01-17 06:56:22 +00003840 default: llvm_unreachable("unexpected attribute kind");
John McCall3882ace2011-01-05 12:14:39 +00003841 }
3842
Aaron Ballmane91c6be2012-10-02 14:26:08 +00003843 const TargetInfo &TI = Context.getTargetInfo();
3844 TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC);
3845 if (A == TargetInfo::CCCR_Warning) {
3846 Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName();
Aaron Ballman02df2e02012-12-09 17:45:41 +00003847
3848 TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown;
3849 if (FD)
3850 MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member :
3851 TargetInfo::CCMT_NonMember;
3852 CC = TI.getDefaultCallingConv(MT);
Aaron Ballmane91c6be2012-10-02 14:26:08 +00003853 }
3854
John McCall3882ace2011-01-05 12:14:39 +00003855 return false;
3856}
3857
Chandler Carruthedc2c642011-07-02 00:01:44 +00003858static void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003859 if (hasDeclarator(D)) return;
John McCall3882ace2011-01-05 12:14:39 +00003860
3861 unsigned numParams;
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003862 if (S.CheckRegparmAttr(Attr, numParams))
John McCall3882ace2011-01-05 12:14:39 +00003863 return;
3864
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003865 if (!isa<ObjCMethodDecl>(D)) {
3866 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3867 << Attr.getName() << ExpectedFunctionOrMethod;
Fariborz Jahaniana2d609e2009-03-27 18:38:55 +00003868 return;
3869 }
Eli Friedman7044b762009-03-27 21:06:47 +00003870
Michael Han99315932013-01-24 16:46:58 +00003871 D->addAttr(::new (S.Context)
3872 RegparmAttr(Attr.getRange(), S.Context, numParams,
3873 Attr.getAttributeSpellingListIndex()));
John McCall3882ace2011-01-05 12:14:39 +00003874}
3875
3876/// Checks a regparm attribute, returning true if it is ill-formed and
3877/// otherwise setting numParams to the appropriate value.
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003878bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
3879 if (Attr.isInvalid())
John McCall3882ace2011-01-05 12:14:39 +00003880 return true;
3881
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003882 if (Attr.getNumArgs() != 1) {
3883 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
3884 Attr.setInvalid();
John McCall3882ace2011-01-05 12:14:39 +00003885 return true;
Fariborz Jahaniana2d609e2009-03-27 18:38:55 +00003886 }
Eli Friedman7044b762009-03-27 21:06:47 +00003887
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003888 Expr *NumParamsExpr = Attr.getArg(0);
Eli Friedman7044b762009-03-27 21:06:47 +00003889 llvm::APSInt NumParams(32);
Douglas Gregorbdb604a2010-05-18 23:01:22 +00003890 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
John McCall3882ace2011-01-05 12:14:39 +00003891 !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003892 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
Eli Friedman7044b762009-03-27 21:06:47 +00003893 << "regparm" << NumParamsExpr->getSourceRange();
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003894 Attr.setInvalid();
John McCall3882ace2011-01-05 12:14:39 +00003895 return true;
Eli Friedman7044b762009-03-27 21:06:47 +00003896 }
3897
Douglas Gregore8bbc122011-09-02 00:18:52 +00003898 if (Context.getTargetInfo().getRegParmMax() == 0) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003899 Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
Eli Friedman7044b762009-03-27 21:06:47 +00003900 << NumParamsExpr->getSourceRange();
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003901 Attr.setInvalid();
John McCall3882ace2011-01-05 12:14:39 +00003902 return true;
Eli Friedman7044b762009-03-27 21:06:47 +00003903 }
3904
John McCall3882ace2011-01-05 12:14:39 +00003905 numParams = NumParams.getZExtValue();
Douglas Gregore8bbc122011-09-02 00:18:52 +00003906 if (numParams > Context.getTargetInfo().getRegParmMax()) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003907 Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
Douglas Gregore8bbc122011-09-02 00:18:52 +00003908 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003909 Attr.setInvalid();
John McCall3882ace2011-01-05 12:14:39 +00003910 return true;
Eli Friedman7044b762009-03-27 21:06:47 +00003911 }
3912
John McCall3882ace2011-01-05 12:14:39 +00003913 return false;
Fariborz Jahaniana2d609e2009-03-27 18:38:55 +00003914}
3915
Chandler Carruthedc2c642011-07-02 00:01:44 +00003916static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
Peter Collingbourne827301e2010-12-12 23:03:07 +00003917 if (S.LangOpts.CUDA) {
3918 // check the attribute arguments.
3919 if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
John McCall80ee5962011-03-02 12:15:05 +00003920 // FIXME: 0 is not okay.
3921 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
Peter Collingbourne827301e2010-12-12 23:03:07 +00003922 return;
3923 }
3924
Chandler Carruthff4c4f02011-07-01 23:49:12 +00003925 if (!isFunctionOrMethod(D)) {
Peter Collingbourne827301e2010-12-12 23:03:07 +00003926 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall5fca7ea2011-03-02 12:29:23 +00003927 << Attr.getName() << ExpectedFunctionOrMethod;
Peter Collingbourne827301e2010-12-12 23:03:07 +00003928 return;
3929 }
3930
3931 Expr *MaxThreadsExpr = Attr.getArg(0);
3932 llvm::APSInt MaxThreads(32);
3933 if (MaxThreadsExpr->isTypeDependent() ||
3934 MaxThreadsExpr->isValueDependent() ||
3935 !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
3936 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
3937 << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
3938 return;
3939 }
3940
3941 llvm::APSInt MinBlocks(32);
3942 if (Attr.getNumArgs() > 1) {
3943 Expr *MinBlocksExpr = Attr.getArg(1);
3944 if (MinBlocksExpr->isTypeDependent() ||
3945 MinBlocksExpr->isValueDependent() ||
3946 !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
3947 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
3948 << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
3949 return;
3950 }
3951 }
3952
Michael Han99315932013-01-24 16:46:58 +00003953 D->addAttr(::new (S.Context)
3954 CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
3955 MaxThreads.getZExtValue(),
3956 MinBlocks.getZExtValue(),
3957 Attr.getAttributeSpellingListIndex()));
Peter Collingbourne827301e2010-12-12 23:03:07 +00003958 } else {
3959 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
3960 }
3961}
3962
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00003963static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
3964 const AttributeList &Attr) {
3965 StringRef AttrName = Attr.getName()->getName();
3966 if (!Attr.getParameterName()) {
3967 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier)
3968 << Attr.getName() << /* arg num = */ 1;
3969 return;
3970 }
3971
3972 if (Attr.getNumArgs() != 2) {
3973 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
3974 << /* required args = */ 3;
3975 return;
3976 }
3977
3978 IdentifierInfo *ArgumentKind = Attr.getParameterName();
3979
3980 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
3981 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
3982 << Attr.getName() << ExpectedFunctionOrMethod;
3983 return;
3984 }
3985
3986 uint64_t ArgumentIdx;
3987 if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
3988 Attr.getLoc(), 2,
3989 Attr.getArg(0), ArgumentIdx))
3990 return;
3991
3992 uint64_t TypeTagIdx;
3993 if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
3994 Attr.getLoc(), 3,
3995 Attr.getArg(1), TypeTagIdx))
3996 return;
3997
3998 bool IsPointer = (AttrName == "pointer_with_type_tag");
3999 if (IsPointer) {
4000 // Ensure that buffer has a pointer type.
4001 QualType BufferTy = getFunctionOrMethodArgType(D, ArgumentIdx);
4002 if (!BufferTy->isPointerType()) {
4003 S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only)
4004 << AttrName;
4005 }
4006 }
4007
Michael Han99315932013-01-24 16:46:58 +00004008 D->addAttr(::new (S.Context)
4009 ArgumentWithTypeTagAttr(Attr.getRange(), S.Context, ArgumentKind,
4010 ArgumentIdx, TypeTagIdx, IsPointer,
4011 Attr.getAttributeSpellingListIndex()));
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00004012}
4013
4014static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
4015 const AttributeList &Attr) {
4016 IdentifierInfo *PointerKind = Attr.getParameterName();
4017 if (!PointerKind) {
4018 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier)
4019 << "type_tag_for_datatype" << 1;
4020 return;
4021 }
4022
4023 QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL);
4024
Michael Han99315932013-01-24 16:46:58 +00004025 D->addAttr(::new (S.Context)
4026 TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind,
4027 MatchingCType,
4028 Attr.getLayoutCompatible(),
4029 Attr.getMustBeNull(),
4030 Attr.getAttributeSpellingListIndex()));
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00004031}
4032
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004033//===----------------------------------------------------------------------===//
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00004034// Checker-specific attribute handlers.
4035//===----------------------------------------------------------------------===//
4036
John McCalled433932011-01-25 03:31:58 +00004037static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
Douglas Gregorf892c7f2011-10-09 22:26:49 +00004038 return type->isDependentType() ||
4039 type->isObjCObjectPointerType() ||
4040 S.Context.isObjCNSObjectType(type);
John McCalled433932011-01-25 03:31:58 +00004041}
4042static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
Douglas Gregorf892c7f2011-10-09 22:26:49 +00004043 return type->isDependentType() ||
4044 type->isPointerType() ||
4045 isValidSubjectOfNSAttribute(S, type);
John McCalled433932011-01-25 03:31:58 +00004046}
4047
Chandler Carruthedc2c642011-07-02 00:01:44 +00004048static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004049 ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
John McCalled433932011-01-25 03:31:58 +00004050 if (!param) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004051 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00004052 << Attr.getRange() << Attr.getName() << ExpectedParameter;
John McCalled433932011-01-25 03:31:58 +00004053 return;
4054 }
4055
4056 bool typeOK, cf;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004057 if (Attr.getKind() == AttributeList::AT_NSConsumed) {
John McCalled433932011-01-25 03:31:58 +00004058 typeOK = isValidSubjectOfNSAttribute(S, param->getType());
4059 cf = false;
4060 } else {
4061 typeOK = isValidSubjectOfCFAttribute(S, param->getType());
4062 cf = true;
4063 }
4064
4065 if (!typeOK) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004066 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00004067 << Attr.getRange() << Attr.getName() << cf;
John McCalled433932011-01-25 03:31:58 +00004068 return;
4069 }
4070
4071 if (cf)
Michael Han99315932013-01-24 16:46:58 +00004072 param->addAttr(::new (S.Context)
4073 CFConsumedAttr(Attr.getRange(), S.Context,
4074 Attr.getAttributeSpellingListIndex()));
John McCalled433932011-01-25 03:31:58 +00004075 else
Michael Han99315932013-01-24 16:46:58 +00004076 param->addAttr(::new (S.Context)
4077 NSConsumedAttr(Attr.getRange(), S.Context,
4078 Attr.getAttributeSpellingListIndex()));
John McCalled433932011-01-25 03:31:58 +00004079}
4080
Chandler Carruthedc2c642011-07-02 00:01:44 +00004081static void handleNSConsumesSelfAttr(Sema &S, Decl *D,
4082 const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004083 if (!isa<ObjCMethodDecl>(D)) {
4084 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00004085 << Attr.getRange() << Attr.getName() << ExpectedMethod;
John McCalled433932011-01-25 03:31:58 +00004086 return;
4087 }
4088
Michael Han99315932013-01-24 16:46:58 +00004089 D->addAttr(::new (S.Context)
4090 NSConsumesSelfAttr(Attr.getRange(), S.Context,
4091 Attr.getAttributeSpellingListIndex()));
John McCalled433932011-01-25 03:31:58 +00004092}
4093
Chandler Carruthedc2c642011-07-02 00:01:44 +00004094static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
4095 const AttributeList &Attr) {
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00004096
John McCalled433932011-01-25 03:31:58 +00004097 QualType returnType;
Mike Stumpd3bb5572009-07-24 19:02:52 +00004098
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004099 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
John McCalled433932011-01-25 03:31:58 +00004100 returnType = MD->getResultType();
David Blaikiebbafb8a2012-03-11 07:00:24 +00004101 else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004102 (Attr.getKind() == AttributeList::AT_NSReturnsRetained))
John McCall31168b02011-06-15 23:02:42 +00004103 return; // ignore: was handled as a type attribute
Fariborz Jahanian272b7dc2012-08-28 22:26:21 +00004104 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
4105 returnType = PD->getType();
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004106 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
John McCalled433932011-01-25 03:31:58 +00004107 returnType = FD->getResultType();
Ted Kremenek3b204e42009-05-13 21:07:32 +00004108 else {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004109 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00004110 << Attr.getRange() << Attr.getName()
John McCall5fca7ea2011-03-02 12:29:23 +00004111 << ExpectedFunctionOrMethod;
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00004112 return;
4113 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00004114
John McCalled433932011-01-25 03:31:58 +00004115 bool typeOK;
4116 bool cf;
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004117 switch (Attr.getKind()) {
David Blaikie8a40f702012-01-17 06:56:22 +00004118 default: llvm_unreachable("invalid ownership attribute");
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004119 case AttributeList::AT_NSReturnsAutoreleased:
4120 case AttributeList::AT_NSReturnsRetained:
4121 case AttributeList::AT_NSReturnsNotRetained:
John McCalled433932011-01-25 03:31:58 +00004122 typeOK = isValidSubjectOfNSAttribute(S, returnType);
4123 cf = false;
4124 break;
4125
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004126 case AttributeList::AT_CFReturnsRetained:
4127 case AttributeList::AT_CFReturnsNotRetained:
John McCalled433932011-01-25 03:31:58 +00004128 typeOK = isValidSubjectOfCFAttribute(S, returnType);
4129 cf = true;
4130 break;
4131 }
4132
4133 if (!typeOK) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004134 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
Argyrios Kyrtzidis309b4c42011-09-13 16:05:58 +00004135 << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
Mike Stumpd3bb5572009-07-24 19:02:52 +00004136 return;
Ted Kremenek3b204e42009-05-13 21:07:32 +00004137 }
Mike Stumpd3bb5572009-07-24 19:02:52 +00004138
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004139 switch (Attr.getKind()) {
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00004140 default:
David Blaikie83d382b2011-09-23 05:06:16 +00004141 llvm_unreachable("invalid ownership attribute");
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004142 case AttributeList::AT_NSReturnsAutoreleased:
Michael Han99315932013-01-24 16:46:58 +00004143 D->addAttr(::new (S.Context)
4144 NSReturnsAutoreleasedAttr(Attr.getRange(), S.Context,
4145 Attr.getAttributeSpellingListIndex()));
John McCalled433932011-01-25 03:31:58 +00004146 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004147 case AttributeList::AT_CFReturnsNotRetained:
Michael Han99315932013-01-24 16:46:58 +00004148 D->addAttr(::new (S.Context)
4149 CFReturnsNotRetainedAttr(Attr.getRange(), S.Context,
4150 Attr.getAttributeSpellingListIndex()));
Ted Kremenekd9c66632010-02-18 00:05:45 +00004151 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004152 case AttributeList::AT_NSReturnsNotRetained:
Michael Han99315932013-01-24 16:46:58 +00004153 D->addAttr(::new (S.Context)
4154 NSReturnsNotRetainedAttr(Attr.getRange(), S.Context,
4155 Attr.getAttributeSpellingListIndex()));
Ted Kremenekd9c66632010-02-18 00:05:45 +00004156 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004157 case AttributeList::AT_CFReturnsRetained:
Michael Han99315932013-01-24 16:46:58 +00004158 D->addAttr(::new (S.Context)
4159 CFReturnsRetainedAttr(Attr.getRange(), S.Context,
4160 Attr.getAttributeSpellingListIndex()));
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00004161 return;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004162 case AttributeList::AT_NSReturnsRetained:
Michael Han99315932013-01-24 16:46:58 +00004163 D->addAttr(::new (S.Context)
4164 NSReturnsRetainedAttr(Attr.getRange(), S.Context,
4165 Attr.getAttributeSpellingListIndex()));
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00004166 return;
4167 };
4168}
4169
John McCallcf166702011-07-22 08:53:00 +00004170static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
4171 const AttributeList &attr) {
4172 SourceLocation loc = attr.getLoc();
4173
4174 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
4175
Fariborz Jahaniana53e5d72012-04-21 17:51:44 +00004176 if (!method) {
Fariborz Jahanian344d65c2012-04-20 22:00:46 +00004177 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
Douglas Gregor5c3cc422012-03-14 16:55:17 +00004178 << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
John McCallcf166702011-07-22 08:53:00 +00004179 return;
4180 }
4181
4182 // Check that the method returns a normal pointer.
4183 QualType resultType = method->getResultType();
Fariborz Jahanian044a5be2011-09-30 20:50:23 +00004184
4185 if (!resultType->isReferenceType() &&
4186 (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
John McCallcf166702011-07-22 08:53:00 +00004187 S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
4188 << SourceRange(loc)
4189 << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
4190
4191 // Drop the attribute.
4192 return;
4193 }
4194
Michael Han99315932013-01-24 16:46:58 +00004195 method->addAttr(::new (S.Context)
4196 ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context,
4197 attr.getAttributeSpellingListIndex()));
John McCallcf166702011-07-22 08:53:00 +00004198}
4199
Fariborz Jahanian566fff02012-09-07 23:46:23 +00004200static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
4201 const AttributeList &attr) {
4202 SourceLocation loc = attr.getLoc();
4203 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
4204
4205 if (!method) {
4206 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4207 << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
4208 return;
4209 }
4210 DeclContext *DC = method->getDeclContext();
4211 if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) {
4212 S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
4213 << attr.getName() << 0;
4214 S.Diag(PDecl->getLocation(), diag::note_protocol_decl);
4215 return;
4216 }
4217 if (method->getMethodFamily() == OMF_dealloc) {
4218 S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
4219 << attr.getName() << 1;
4220 return;
4221 }
4222
Michael Han99315932013-01-24 16:46:58 +00004223 method->addAttr(::new (S.Context)
4224 ObjCRequiresSuperAttr(attr.getRange(), S.Context,
4225 attr.getAttributeSpellingListIndex()));
Fariborz Jahanian566fff02012-09-07 23:46:23 +00004226}
4227
John McCall32f5fe12011-09-30 05:12:12 +00004228/// Handle cf_audited_transfer and cf_unknown_transfer.
4229static void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
4230 if (!isa<FunctionDecl>(D)) {
4231 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
Douglas Gregor5c3cc422012-03-14 16:55:17 +00004232 << A.getRange() << A.getName() << ExpectedFunction;
John McCall32f5fe12011-09-30 05:12:12 +00004233 return;
4234 }
4235
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004236 bool IsAudited = (A.getKind() == AttributeList::AT_CFAuditedTransfer);
John McCall32f5fe12011-09-30 05:12:12 +00004237
4238 // Check whether there's a conflicting attribute already present.
4239 Attr *Existing;
4240 if (IsAudited) {
4241 Existing = D->getAttr<CFUnknownTransferAttr>();
4242 } else {
4243 Existing = D->getAttr<CFAuditedTransferAttr>();
4244 }
4245 if (Existing) {
4246 S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
4247 << A.getName()
4248 << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
4249 << A.getRange() << Existing->getRange();
4250 return;
4251 }
4252
4253 // All clear; add the attribute.
4254 if (IsAudited) {
Michael Han99315932013-01-24 16:46:58 +00004255 D->addAttr(::new (S.Context)
4256 CFAuditedTransferAttr(A.getRange(), S.Context,
4257 A.getAttributeSpellingListIndex()));
John McCall32f5fe12011-09-30 05:12:12 +00004258 } else {
Michael Han99315932013-01-24 16:46:58 +00004259 D->addAttr(::new (S.Context)
4260 CFUnknownTransferAttr(A.getRange(), S.Context,
4261 A.getAttributeSpellingListIndex()));
John McCall32f5fe12011-09-30 05:12:12 +00004262 }
4263}
4264
John McCallf1e8b342011-09-29 07:17:38 +00004265static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
4266 const AttributeList &Attr) {
4267 RecordDecl *RD = dyn_cast<RecordDecl>(D);
4268 if (!RD || RD->isUnion()) {
4269 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
Douglas Gregor5c3cc422012-03-14 16:55:17 +00004270 << Attr.getRange() << Attr.getName() << ExpectedStruct;
John McCallf1e8b342011-09-29 07:17:38 +00004271 }
4272
4273 IdentifierInfo *ParmName = Attr.getParameterName();
4274
4275 // In Objective-C, verify that the type names an Objective-C type.
4276 // We don't want to check this outside of ObjC because people sometimes
4277 // do crazy C declarations of Objective-C types.
David Blaikiebbafb8a2012-03-11 07:00:24 +00004278 if (ParmName && S.getLangOpts().ObjC1) {
John McCallf1e8b342011-09-29 07:17:38 +00004279 // Check for an existing type with this name.
4280 LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
4281 Sema::LookupOrdinaryName);
4282 if (S.LookupName(R, Sc)) {
4283 NamedDecl *Target = R.getFoundDecl();
4284 if (Target && !isa<ObjCInterfaceDecl>(Target)) {
4285 S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
4286 S.Diag(Target->getLocStart(), diag::note_declared_at);
4287 }
4288 }
4289 }
4290
Michael Han99315932013-01-24 16:46:58 +00004291 D->addAttr(::new (S.Context)
4292 NSBridgedAttr(Attr.getRange(), S.Context, ParmName,
4293 Attr.getAttributeSpellingListIndex()));
John McCallf1e8b342011-09-29 07:17:38 +00004294}
4295
Chandler Carruthedc2c642011-07-02 00:01:44 +00004296static void handleObjCOwnershipAttr(Sema &S, Decl *D,
4297 const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004298 if (hasDeclarator(D)) return;
John McCall31168b02011-06-15 23:02:42 +00004299
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004300 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
Douglas Gregor5c3cc422012-03-14 16:55:17 +00004301 << Attr.getRange() << Attr.getName() << ExpectedVariable;
John McCall31168b02011-06-15 23:02:42 +00004302}
4303
Chandler Carruthedc2c642011-07-02 00:01:44 +00004304static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
4305 const AttributeList &Attr) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004306 if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004307 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
Douglas Gregor5c3cc422012-03-14 16:55:17 +00004308 << Attr.getRange() << Attr.getName() << ExpectedVariable;
John McCall31168b02011-06-15 23:02:42 +00004309 return;
4310 }
4311
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004312 ValueDecl *vd = cast<ValueDecl>(D);
John McCall31168b02011-06-15 23:02:42 +00004313 QualType type = vd->getType();
4314
4315 if (!type->isDependentType() &&
4316 !type->isObjCLifetimeType()) {
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004317 S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
John McCall31168b02011-06-15 23:02:42 +00004318 << type;
4319 return;
4320 }
4321
4322 Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
4323
4324 // If we have no lifetime yet, check the lifetime we're presumably
4325 // going to infer.
4326 if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
4327 lifetime = type->getObjCARCImplicitLifetime();
4328
4329 switch (lifetime) {
4330 case Qualifiers::OCL_None:
4331 assert(type->isDependentType() &&
4332 "didn't infer lifetime for non-dependent type?");
4333 break;
4334
4335 case Qualifiers::OCL_Weak: // meaningful
4336 case Qualifiers::OCL_Strong: // meaningful
4337 break;
4338
4339 case Qualifiers::OCL_ExplicitNone:
4340 case Qualifiers::OCL_Autoreleasing:
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004341 S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
John McCall31168b02011-06-15 23:02:42 +00004342 << (lifetime == Qualifiers::OCL_Autoreleasing);
4343 break;
4344 }
4345
Chandler Carruthff4c4f02011-07-01 23:49:12 +00004346 D->addAttr(::new (S.Context)
Michael Han99315932013-01-24 16:46:58 +00004347 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context,
4348 Attr.getAttributeSpellingListIndex()));
John McCall31168b02011-06-15 23:02:42 +00004349}
4350
Francois Picheta83957a2010-12-19 06:50:37 +00004351//===----------------------------------------------------------------------===//
4352// Microsoft specific attribute handlers.
4353//===----------------------------------------------------------------------===//
4354
Chandler Carruthedc2c642011-07-02 00:01:44 +00004355static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Francois Pichet0706d202011-09-17 17:15:52 +00004356 if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
Francois Picheta83957a2010-12-19 06:50:37 +00004357 // check the attribute arguments.
Chandler Carruthfcc48d92011-07-11 23:30:35 +00004358 if (!checkAttributeNumArgs(S, Attr, 1))
Francois Picheta83957a2010-12-19 06:50:37 +00004359 return;
Chandler Carruthfcc48d92011-07-11 23:30:35 +00004360
Francois Picheta83957a2010-12-19 06:50:37 +00004361 Expr *Arg = Attr.getArg(0);
4362 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
Douglas Gregorfb65e592011-07-27 05:40:30 +00004363 if (!Str || !Str->isAscii()) {
Francois Pichet7da11662010-12-20 01:41:49 +00004364 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
4365 << "uuid" << 1;
4366 return;
4367 }
4368
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004369 StringRef StrRef = Str->getString();
Francois Pichet7da11662010-12-20 01:41:49 +00004370
4371 bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
4372 StrRef.back() == '}';
Douglas Gregor5c3cc422012-03-14 16:55:17 +00004373
Francois Pichet7da11662010-12-20 01:41:49 +00004374 // Validate GUID length.
4375 if (IsCurly && StrRef.size() != 38) {
4376 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4377 return;
4378 }
4379 if (!IsCurly && StrRef.size() != 36) {
4380 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4381 return;
4382 }
4383
Douglas Gregor5c3cc422012-03-14 16:55:17 +00004384 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
Francois Pichet7da11662010-12-20 01:41:49 +00004385 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004386 StringRef::iterator I = StrRef.begin();
Anders Carlsson19588aa2011-01-23 21:07:30 +00004387 if (IsCurly) // Skip the optional '{'
4388 ++I;
4389
4390 for (int i = 0; i < 36; ++i) {
Francois Pichet7da11662010-12-20 01:41:49 +00004391 if (i == 8 || i == 13 || i == 18 || i == 23) {
4392 if (*I != '-') {
4393 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4394 return;
4395 }
4396 } else if (!isxdigit(*I)) {
4397 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4398 return;
4399 }
4400 I++;
4401 }
Francois Picheta83957a2010-12-19 06:50:37 +00004402
Michael Han99315932013-01-24 16:46:58 +00004403 D->addAttr(::new (S.Context)
4404 UuidAttr(Attr.getRange(), S.Context, Str->getString(),
4405 Attr.getAttributeSpellingListIndex()));
Francois Pichet7da11662010-12-20 01:41:49 +00004406 } else
Francois Picheta83957a2010-12-19 06:50:37 +00004407 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
Charles Davis163855f2010-02-16 18:27:26 +00004408}
4409
John McCall8d32c052012-05-22 21:28:12 +00004410static void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Nico Weberefa45b22012-11-07 21:31:36 +00004411 if (!S.LangOpts.MicrosoftExt) {
John McCall8d32c052012-05-22 21:28:12 +00004412 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
Nico Weberefa45b22012-11-07 21:31:36 +00004413 return;
4414 }
4415
4416 AttributeList::Kind Kind = Attr.getKind();
4417 if (Kind == AttributeList::AT_SingleInheritance)
4418 D->addAttr(
Michael Han99315932013-01-24 16:46:58 +00004419 ::new (S.Context)
4420 SingleInheritanceAttr(Attr.getRange(), S.Context,
4421 Attr.getAttributeSpellingListIndex()));
Nico Weberefa45b22012-11-07 21:31:36 +00004422 else if (Kind == AttributeList::AT_MultipleInheritance)
4423 D->addAttr(
Michael Han99315932013-01-24 16:46:58 +00004424 ::new (S.Context)
4425 MultipleInheritanceAttr(Attr.getRange(), S.Context,
4426 Attr.getAttributeSpellingListIndex()));
Nico Weberefa45b22012-11-07 21:31:36 +00004427 else if (Kind == AttributeList::AT_VirtualInheritance)
4428 D->addAttr(
Michael Han99315932013-01-24 16:46:58 +00004429 ::new (S.Context)
4430 VirtualInheritanceAttr(Attr.getRange(), S.Context,
4431 Attr.getAttributeSpellingListIndex()));
John McCall8d32c052012-05-22 21:28:12 +00004432}
4433
4434static void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4435 if (S.LangOpts.MicrosoftExt) {
4436 AttributeList::Kind Kind = Attr.getKind();
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004437 if (Kind == AttributeList::AT_Ptr32)
John McCall8d32c052012-05-22 21:28:12 +00004438 D->addAttr(
Michael Han99315932013-01-24 16:46:58 +00004439 ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context,
4440 Attr.getAttributeSpellingListIndex()));
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004441 else if (Kind == AttributeList::AT_Ptr64)
John McCall8d32c052012-05-22 21:28:12 +00004442 D->addAttr(
Michael Han99315932013-01-24 16:46:58 +00004443 ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context,
4444 Attr.getAttributeSpellingListIndex()));
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004445 else if (Kind == AttributeList::AT_Win64)
John McCall8d32c052012-05-22 21:28:12 +00004446 D->addAttr(
Michael Han99315932013-01-24 16:46:58 +00004447 ::new (S.Context) Win64Attr(Attr.getRange(), S.Context,
4448 Attr.getAttributeSpellingListIndex()));
John McCall8d32c052012-05-22 21:28:12 +00004449 } else
4450 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4451}
4452
Michael J. Spencerf97bd8c2012-06-18 07:00:48 +00004453static void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4454 if (S.LangOpts.MicrosoftExt)
Michael Han99315932013-01-24 16:46:58 +00004455 D->addAttr(::new (S.Context)
4456 ForceInlineAttr(Attr.getRange(), S.Context,
4457 Attr.getAttributeSpellingListIndex()));
Michael J. Spencerf97bd8c2012-06-18 07:00:48 +00004458 else
4459 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4460}
4461
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00004462//===----------------------------------------------------------------------===//
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004463// Top Level Sema Entry Points
4464//===----------------------------------------------------------------------===//
4465
Chandler Carruthedc2c642011-07-02 00:01:44 +00004466static void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
4467 const AttributeList &Attr) {
Peter Collingbourneb331b262011-01-21 02:08:45 +00004468 switch (Attr.getKind()) {
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004469 case AttributeList::AT_CUDADevice: handleDeviceAttr (S, D, Attr); break;
4470 case AttributeList::AT_CUDAHost: handleHostAttr (S, D, Attr); break;
4471 case AttributeList::AT_Overloadable:handleOverloadableAttr(S, D, Attr); break;
Peter Collingbourneb331b262011-01-21 02:08:45 +00004472 default:
4473 break;
4474 }
4475}
Abramo Bagnara50099372010-04-30 13:10:51 +00004476
Chandler Carruthedc2c642011-07-02 00:01:44 +00004477static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
4478 const AttributeList &Attr) {
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004479 switch (Attr.getKind()) {
Richard Smith10876ef2013-01-17 01:30:42 +00004480 case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break;
4481 case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break;
4482 case AttributeList::AT_IBOutletCollection:
4483 handleIBOutletCollection(S, D, Attr); break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004484 case AttributeList::AT_AddressSpace:
4485 case AttributeList::AT_OpenCLImageAccess:
4486 case AttributeList::AT_ObjCGC:
4487 case AttributeList::AT_VectorSize:
4488 case AttributeList::AT_NeonVectorType:
4489 case AttributeList::AT_NeonPolyVectorType:
Mike Stumpd3bb5572009-07-24 19:02:52 +00004490 // Ignore these, these are type attributes, handled by
4491 // ProcessTypeAttributes.
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004492 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004493 case AttributeList::AT_CUDADevice:
4494 case AttributeList::AT_CUDAHost:
4495 case AttributeList::AT_Overloadable:
Peter Collingbourneb331b262011-01-21 02:08:45 +00004496 // Ignore, this is a non-inheritable attribute, handled
4497 // by ProcessNonInheritableDeclAttr.
4498 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004499 case AttributeList::AT_Alias: handleAliasAttr (S, D, Attr); break;
4500 case AttributeList::AT_Aligned: handleAlignedAttr (S, D, Attr); break;
4501 case AttributeList::AT_AllocSize: handleAllocSizeAttr (S, D, Attr); break;
4502 case AttributeList::AT_AlwaysInline:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004503 handleAlwaysInlineAttr (S, D, Attr); break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004504 case AttributeList::AT_AnalyzerNoReturn:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004505 handleAnalyzerNoReturnAttr (S, D, Attr); break;
Hans Wennborgd3b01bc2012-06-23 11:51:46 +00004506 case AttributeList::AT_TLSModel: handleTLSModelAttr (S, D, Attr); break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004507 case AttributeList::AT_Annotate: handleAnnotateAttr (S, D, Attr); break;
4508 case AttributeList::AT_Availability:handleAvailabilityAttr(S, D, Attr); break;
4509 case AttributeList::AT_CarriesDependency:
Richard Smithe233fbf2013-01-28 22:42:45 +00004510 handleDependencyAttr(S, scope, D, Attr);
4511 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004512 case AttributeList::AT_Common: handleCommonAttr (S, D, Attr); break;
4513 case AttributeList::AT_CUDAConstant:handleConstantAttr (S, D, Attr); break;
4514 case AttributeList::AT_Constructor: handleConstructorAttr (S, D, Attr); break;
Richard Smith10876ef2013-01-17 01:30:42 +00004515 case AttributeList::AT_CXX11NoReturn:
4516 handleCXX11NoReturnAttr(S, D, Attr);
4517 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004518 case AttributeList::AT_Deprecated:
Benjamin Kramerf435ab42012-05-16 12:19:08 +00004519 handleAttrWithMessage<DeprecatedAttr>(S, D, Attr, "deprecated");
4520 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004521 case AttributeList::AT_Destructor: handleDestructorAttr (S, D, Attr); break;
4522 case AttributeList::AT_ExtVectorType:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004523 handleExtVectorTypeAttr(S, scope, D, Attr);
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004524 break;
Quentin Colombet4e172062012-11-01 23:55:47 +00004525 case AttributeList::AT_MinSize:
4526 handleMinSizeAttr(S, D, Attr);
4527 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004528 case AttributeList::AT_Format: handleFormatAttr (S, D, Attr); break;
4529 case AttributeList::AT_FormatArg: handleFormatArgAttr (S, D, Attr); break;
4530 case AttributeList::AT_CUDAGlobal: handleGlobalAttr (S, D, Attr); break;
4531 case AttributeList::AT_GNUInline: handleGNUInlineAttr (S, D, Attr); break;
4532 case AttributeList::AT_CUDALaunchBounds:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004533 handleLaunchBoundsAttr(S, D, Attr);
Peter Collingbourne827301e2010-12-12 23:03:07 +00004534 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004535 case AttributeList::AT_Mode: handleModeAttr (S, D, Attr); break;
4536 case AttributeList::AT_Malloc: handleMallocAttr (S, D, Attr); break;
4537 case AttributeList::AT_MayAlias: handleMayAliasAttr (S, D, Attr); break;
4538 case AttributeList::AT_NoCommon: handleNoCommonAttr (S, D, Attr); break;
4539 case AttributeList::AT_NonNull: handleNonNullAttr (S, D, Attr); break;
Ted Kremenekd21139a2010-07-31 01:52:11 +00004540 case AttributeList::AT_ownership_returns:
4541 case AttributeList::AT_ownership_takes:
4542 case AttributeList::AT_ownership_holds:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004543 handleOwnershipAttr (S, D, Attr); break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004544 case AttributeList::AT_Cold: handleColdAttr (S, D, Attr); break;
4545 case AttributeList::AT_Hot: handleHotAttr (S, D, Attr); break;
4546 case AttributeList::AT_Naked: handleNakedAttr (S, D, Attr); break;
4547 case AttributeList::AT_NoReturn: handleNoReturnAttr (S, D, Attr); break;
4548 case AttributeList::AT_NoThrow: handleNothrowAttr (S, D, Attr); break;
4549 case AttributeList::AT_CUDAShared: handleSharedAttr (S, D, Attr); break;
4550 case AttributeList::AT_VecReturn: handleVecReturnAttr (S, D, Attr); break;
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00004551
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004552 case AttributeList::AT_ObjCOwnership:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004553 handleObjCOwnershipAttr(S, D, Attr); break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004554 case AttributeList::AT_ObjCPreciseLifetime:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004555 handleObjCPreciseLifetimeAttr(S, D, Attr); break;
John McCall31168b02011-06-15 23:02:42 +00004556
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004557 case AttributeList::AT_ObjCReturnsInnerPointer:
John McCallcf166702011-07-22 08:53:00 +00004558 handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
4559
Fariborz Jahanian566fff02012-09-07 23:46:23 +00004560 case AttributeList::AT_ObjCRequiresSuper:
4561 handleObjCRequiresSuperAttr(S, D, Attr); break;
4562
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004563 case AttributeList::AT_NSBridged:
John McCallf1e8b342011-09-29 07:17:38 +00004564 handleNSBridgedAttr(S, scope, D, Attr); break;
4565
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004566 case AttributeList::AT_CFAuditedTransfer:
4567 case AttributeList::AT_CFUnknownTransfer:
John McCall32f5fe12011-09-30 05:12:12 +00004568 handleCFTransferAttr(S, D, Attr); break;
4569
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00004570 // Checker-specific.
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004571 case AttributeList::AT_CFConsumed:
4572 case AttributeList::AT_NSConsumed: handleNSConsumedAttr (S, D, Attr); break;
4573 case AttributeList::AT_NSConsumesSelf:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004574 handleNSConsumesSelfAttr(S, D, Attr); break;
John McCalled433932011-01-25 03:31:58 +00004575
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004576 case AttributeList::AT_NSReturnsAutoreleased:
4577 case AttributeList::AT_NSReturnsNotRetained:
4578 case AttributeList::AT_CFReturnsNotRetained:
4579 case AttributeList::AT_NSReturnsRetained:
4580 case AttributeList::AT_CFReturnsRetained:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004581 handleNSReturnsRetainedAttr(S, D, Attr); break;
Ted Kremenek9ecdfaf2009-05-09 02:44:38 +00004582
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00004583 case AttributeList::AT_WorkGroupSizeHint:
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004584 case AttributeList::AT_ReqdWorkGroupSize:
Tanya Lattnerbcffcdf2012-07-09 22:06:01 +00004585 handleWorkGroupSize(S, D, Attr); break;
Nate Begemanf2758702009-06-26 06:32:41 +00004586
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004587 case AttributeList::AT_InitPriority:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004588 handleInitPriorityAttr(S, D, Attr); break;
Fariborz Jahanianef5f6212010-06-18 21:44:06 +00004589
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004590 case AttributeList::AT_Packed: handlePackedAttr (S, D, Attr); break;
4591 case AttributeList::AT_Section: handleSectionAttr (S, D, Attr); break;
4592 case AttributeList::AT_Unavailable:
Benjamin Kramerf435ab42012-05-16 12:19:08 +00004593 handleAttrWithMessage<UnavailableAttr>(S, D, Attr, "unavailable");
4594 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004595 case AttributeList::AT_ArcWeakrefUnavailable:
Fariborz Jahanian1f626d62011-07-06 19:24:05 +00004596 handleArcWeakrefUnavailableAttr (S, D, Attr);
4597 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004598 case AttributeList::AT_ObjCRootClass:
Patrick Beardacfbe9e2012-04-06 18:12:22 +00004599 handleObjCRootClassAttr(S, D, Attr);
4600 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004601 case AttributeList::AT_ObjCRequiresPropertyDefs:
Ted Kremenek0c2c90b2012-01-05 22:47:47 +00004602 handleObjCRequiresPropertyDefsAttr (S, D, Attr);
Fariborz Jahanian9d4d20a2012-01-03 18:45:41 +00004603 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004604 case AttributeList::AT_Unused: handleUnusedAttr (S, D, Attr); break;
4605 case AttributeList::AT_ReturnsTwice:
Rafael Espindola70107f92011-10-03 14:59:42 +00004606 handleReturnsTwiceAttr(S, D, Attr);
4607 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004608 case AttributeList::AT_Used: handleUsedAttr (S, D, Attr); break;
4609 case AttributeList::AT_Visibility: handleVisibilityAttr (S, D, Attr); break;
4610 case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr);
Chris Lattner237f2752009-02-14 07:37:35 +00004611 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004612 case AttributeList::AT_Weak: handleWeakAttr (S, D, Attr); break;
4613 case AttributeList::AT_WeakRef: handleWeakRefAttr (S, D, Attr); break;
4614 case AttributeList::AT_WeakImport: handleWeakImportAttr (S, D, Attr); break;
4615 case AttributeList::AT_TransparentUnion:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004616 handleTransparentUnionAttr(S, D, Attr);
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004617 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004618 case AttributeList::AT_ObjCException:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004619 handleObjCExceptionAttr(S, D, Attr);
Chris Lattner677a3582009-02-14 08:09:34 +00004620 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004621 case AttributeList::AT_ObjCMethodFamily:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004622 handleObjCMethodFamilyAttr(S, D, Attr);
John McCall86bc21f2011-03-02 11:33:24 +00004623 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004624 case AttributeList::AT_ObjCNSObject:handleObjCNSObject (S, D, Attr); break;
4625 case AttributeList::AT_Blocks: handleBlocksAttr (S, D, Attr); break;
4626 case AttributeList::AT_Sentinel: handleSentinelAttr (S, D, Attr); break;
4627 case AttributeList::AT_Const: handleConstAttr (S, D, Attr); break;
4628 case AttributeList::AT_Pure: handlePureAttr (S, D, Attr); break;
4629 case AttributeList::AT_Cleanup: handleCleanupAttr (S, D, Attr); break;
4630 case AttributeList::AT_NoDebug: handleNoDebugAttr (S, D, Attr); break;
4631 case AttributeList::AT_NoInline: handleNoInlineAttr (S, D, Attr); break;
4632 case AttributeList::AT_Regparm: handleRegparmAttr (S, D, Attr); break;
Mike Stumpd3bb5572009-07-24 19:02:52 +00004633 case AttributeList::IgnoredAttribute:
Anders Carlssonb4f31342009-02-13 08:16:43 +00004634 // Just ignore
4635 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004636 case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg.
Chandler Carruthedc2c642011-07-02 00:01:44 +00004637 handleNoInstrumentFunctionAttr(S, D, Attr);
Chris Lattner3c77a352010-06-22 00:03:40 +00004638 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004639 case AttributeList::AT_StdCall:
4640 case AttributeList::AT_CDecl:
4641 case AttributeList::AT_FastCall:
4642 case AttributeList::AT_ThisCall:
4643 case AttributeList::AT_Pascal:
4644 case AttributeList::AT_Pcs:
Derek Schuffa2020962012-10-16 22:30:41 +00004645 case AttributeList::AT_PnaclCall:
Guy Benyeif0a014b2012-12-25 08:53:55 +00004646 case AttributeList::AT_IntelOclBicc:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004647 handleCallConvAttr(S, D, Attr);
John McCallab26cfa2010-02-05 21:31:56 +00004648 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004649 case AttributeList::AT_OpenCLKernel:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004650 handleOpenCLKernelAttr(S, D, Attr);
Peter Collingbourne7ce13fc2011-02-14 01:42:53 +00004651 break;
John McCall8d32c052012-05-22 21:28:12 +00004652
4653 // Microsoft attributes:
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004654 case AttributeList::AT_MsStruct:
John McCall8d32c052012-05-22 21:28:12 +00004655 handleMsStructAttr(S, D, Attr);
4656 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004657 case AttributeList::AT_Uuid:
Chandler Carruthedc2c642011-07-02 00:01:44 +00004658 handleUuidAttr(S, D, Attr);
Francois Picheta83957a2010-12-19 06:50:37 +00004659 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004660 case AttributeList::AT_SingleInheritance:
4661 case AttributeList::AT_MultipleInheritance:
4662 case AttributeList::AT_VirtualInheritance:
John McCall8d32c052012-05-22 21:28:12 +00004663 handleInheritanceAttr(S, D, Attr);
4664 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004665 case AttributeList::AT_Win64:
4666 case AttributeList::AT_Ptr32:
4667 case AttributeList::AT_Ptr64:
John McCall8d32c052012-05-22 21:28:12 +00004668 handlePortabilityAttr(S, D, Attr);
4669 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004670 case AttributeList::AT_ForceInline:
Michael J. Spencerf97bd8c2012-06-18 07:00:48 +00004671 handleForceInlineAttr(S, D, Attr);
4672 break;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +00004673
4674 // Thread safety attributes:
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004675 case AttributeList::AT_GuardedVar:
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +00004676 handleGuardedVarAttr(S, D, Attr);
4677 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004678 case AttributeList::AT_PtGuardedVar:
Michael Han3be3b442012-07-23 18:48:41 +00004679 handlePtGuardedVarAttr(S, D, Attr);
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +00004680 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004681 case AttributeList::AT_ScopedLockable:
Michael Han3be3b442012-07-23 18:48:41 +00004682 handleScopedLockableAttr(S, D, Attr);
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +00004683 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004684 case AttributeList::AT_NoAddressSafetyAnalysis:
Kostya Serebryany588d6ab2012-01-24 19:25:38 +00004685 handleNoAddressSafetyAttr(S, D, Attr);
4686 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004687 case AttributeList::AT_NoThreadSafetyAnalysis:
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +00004688 handleNoThreadSafetyAttr(S, D, Attr);
4689 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004690 case AttributeList::AT_Lockable:
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +00004691 handleLockableAttr(S, D, Attr);
4692 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004693 case AttributeList::AT_GuardedBy:
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004694 handleGuardedByAttr(S, D, Attr);
4695 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004696 case AttributeList::AT_PtGuardedBy:
Michael Han3be3b442012-07-23 18:48:41 +00004697 handlePtGuardedByAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004698 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004699 case AttributeList::AT_ExclusiveLockFunction:
Michael Han3be3b442012-07-23 18:48:41 +00004700 handleExclusiveLockFunctionAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004701 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004702 case AttributeList::AT_ExclusiveLocksRequired:
Michael Han3be3b442012-07-23 18:48:41 +00004703 handleExclusiveLocksRequiredAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004704 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004705 case AttributeList::AT_ExclusiveTrylockFunction:
Michael Han3be3b442012-07-23 18:48:41 +00004706 handleExclusiveTrylockFunctionAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004707 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004708 case AttributeList::AT_LockReturned:
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004709 handleLockReturnedAttr(S, D, Attr);
4710 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004711 case AttributeList::AT_LocksExcluded:
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004712 handleLocksExcludedAttr(S, D, Attr);
4713 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004714 case AttributeList::AT_SharedLockFunction:
Michael Han3be3b442012-07-23 18:48:41 +00004715 handleSharedLockFunctionAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004716 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004717 case AttributeList::AT_SharedLocksRequired:
Michael Han3be3b442012-07-23 18:48:41 +00004718 handleSharedLocksRequiredAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004719 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004720 case AttributeList::AT_SharedTrylockFunction:
Michael Han3be3b442012-07-23 18:48:41 +00004721 handleSharedTrylockFunctionAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004722 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004723 case AttributeList::AT_UnlockFunction:
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004724 handleUnlockFunAttr(S, D, Attr);
4725 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004726 case AttributeList::AT_AcquiredBefore:
Michael Han3be3b442012-07-23 18:48:41 +00004727 handleAcquiredBeforeAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004728 break;
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004729 case AttributeList::AT_AcquiredAfter:
Michael Han3be3b442012-07-23 18:48:41 +00004730 handleAcquiredAfterAttr(S, D, Attr);
Caitlin Sadowski63fa6672011-07-28 20:12:35 +00004731 break;
Caitlin Sadowskiaac4d212011-07-28 17:21:07 +00004732
Dmitri Gribenkoe4a5a902012-08-17 00:08:38 +00004733 // Type safety attributes.
4734 case AttributeList::AT_ArgumentWithTypeTag:
4735 handleArgumentWithTypeTagAttr(S, D, Attr);
4736 break;
4737 case AttributeList::AT_TypeTagForDatatype:
4738 handleTypeTagForDatatypeAttr(S, D, Attr);
4739 break;
4740
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004741 default:
Anton Korobeynikov55bcea12010-01-10 12:58:08 +00004742 // Ask target about the attribute.
4743 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
4744 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
Aaron Ballman478faed2012-06-19 22:09:27 +00004745 S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ?
4746 diag::warn_unhandled_ms_attribute_ignored :
4747 diag::warn_unknown_attribute_ignored) << Attr.getName();
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004748 break;
4749 }
4750}
4751
Peter Collingbourneb331b262011-01-21 02:08:45 +00004752/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
4753/// the attribute applies to decls. If the attribute is a type attribute, just
Richard Smith10876ef2013-01-17 01:30:42 +00004754/// silently ignore it if a GNU attribute.
Chandler Carruthedc2c642011-07-02 00:01:44 +00004755static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
4756 const AttributeList &Attr,
Richard Smith10876ef2013-01-17 01:30:42 +00004757 bool NonInheritable, bool Inheritable,
4758 bool IncludeCXX11Attributes) {
Peter Collingbourneb331b262011-01-21 02:08:45 +00004759 if (Attr.isInvalid())
4760 return;
4761
Richard Smith10876ef2013-01-17 01:30:42 +00004762 // Ignore C++11 attributes on declarator chunks: they appertain to the type
4763 // instead.
4764 if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes)
4765 return;
4766
Peter Collingbourneb331b262011-01-21 02:08:45 +00004767 if (NonInheritable)
Chandler Carruthedc2c642011-07-02 00:01:44 +00004768 ProcessNonInheritableDeclAttr(S, scope, D, Attr);
Peter Collingbourneb331b262011-01-21 02:08:45 +00004769
4770 if (Inheritable)
Chandler Carruthedc2c642011-07-02 00:01:44 +00004771 ProcessInheritableDeclAttr(S, scope, D, Attr);
Peter Collingbourneb331b262011-01-21 02:08:45 +00004772}
4773
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004774/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
4775/// attribute list to the specified decl, ignoring any type attributes.
Eric Christopherbc638a82010-12-01 22:13:54 +00004776void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
Peter Collingbourneb331b262011-01-21 02:08:45 +00004777 const AttributeList *AttrList,
Richard Smith10876ef2013-01-17 01:30:42 +00004778 bool NonInheritable, bool Inheritable,
4779 bool IncludeCXX11Attributes) {
4780 for (const AttributeList* l = AttrList; l; l = l->getNext())
4781 ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable,
4782 IncludeCXX11Attributes);
Rafael Espindolac18086a2010-02-23 22:00:30 +00004783
4784 // GCC accepts
4785 // static int a9 __attribute__((weakref));
4786 // but that looks really pointless. We reject it.
Peter Collingbourneb331b262011-01-21 02:08:45 +00004787 if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
Rafael Espindolac18086a2010-02-23 22:00:30 +00004788 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
Rafael Espindolab3069002013-01-16 23:49:06 +00004789 cast<NamedDecl>(D)->getNameAsString();
4790 D->dropAttr<WeakRefAttr>();
Rafael Espindolac18086a2010-02-23 22:00:30 +00004791 return;
Chris Lattnerb632a6e2008-06-29 00:43:07 +00004792 }
4793}
4794
Erik Verbruggenca98f2a2011-10-13 09:41:32 +00004795// Annotation attributes are the only attributes allowed after an access
4796// specifier.
4797bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
4798 const AttributeList *AttrList) {
4799 for (const AttributeList* l = AttrList; l; l = l->getNext()) {
Alexis Hunt3bc72c12012-06-19 23:57:03 +00004800 if (l->getKind() == AttributeList::AT_Annotate) {
Erik Verbruggenca98f2a2011-10-13 09:41:32 +00004801 handleAnnotateAttr(*this, ASDecl, *l);
4802 } else {
4803 Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
4804 return true;
4805 }
4806 }
4807
4808 return false;
4809}
4810
John McCall42856de2011-10-01 05:17:03 +00004811/// checkUnusedDeclAttributes - Check a list of attributes to see if it
4812/// contains any decl attributes that we should warn about.
4813static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
4814 for ( ; A; A = A->getNext()) {
4815 // Only warn if the attribute is an unignored, non-type attribute.
4816 if (A->isUsedAsTypeAttr()) continue;
4817 if (A->getKind() == AttributeList::IgnoredAttribute) continue;
4818
4819 if (A->getKind() == AttributeList::UnknownAttribute) {
4820 S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
4821 << A->getName() << A->getRange();
4822 } else {
4823 S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
4824 << A->getName() << A->getRange();
4825 }
4826 }
4827}
4828
4829/// checkUnusedDeclAttributes - Given a declarator which is not being
4830/// used to build a declaration, complain about any decl attributes
4831/// which might be lying around on it.
4832void Sema::checkUnusedDeclAttributes(Declarator &D) {
4833 ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
4834 ::checkUnusedDeclAttributes(*this, D.getAttributes());
4835 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
4836 ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
4837}
4838
Ryan Flynn7d470f32009-07-30 03:15:39 +00004839/// DeclClonePragmaWeak - clone existing decl (maybe definition),
James Dennett634962f2012-06-14 21:40:34 +00004840/// \#pragma weak needs a non-definition decl and source may not have one.
Eli Friedmance3e2c82011-09-07 04:05:06 +00004841NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
4842 SourceLocation Loc) {
Ryan Flynnd963a492009-07-31 02:52:19 +00004843 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
Ryan Flynn7d470f32009-07-30 03:15:39 +00004844 NamedDecl *NewD = 0;
4845 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
Eli Friedmance3e2c82011-09-07 04:05:06 +00004846 FunctionDecl *NewFD;
4847 // FIXME: Missing call to CheckFunctionDeclaration().
4848 // FIXME: Mangling?
4849 // FIXME: Is the qualifier info correct?
4850 // FIXME: Is the DeclContext correct?
4851 NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
4852 Loc, Loc, DeclarationName(II),
4853 FD->getType(), FD->getTypeSourceInfo(),
4854 SC_None, SC_None,
4855 false/*isInlineSpecified*/,
4856 FD->hasPrototype(),
4857 false/*isConstexprSpecified*/);
4858 NewD = NewFD;
4859
4860 if (FD->getQualifier())
Douglas Gregor14454802011-02-25 02:25:35 +00004861 NewFD->setQualifierInfo(FD->getQualifierLoc());
Eli Friedmance3e2c82011-09-07 04:05:06 +00004862
4863 // Fake up parameter variables; they are declared as if this were
4864 // a typedef.
4865 QualType FDTy = FD->getType();
4866 if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
4867 SmallVector<ParmVarDecl*, 16> Params;
4868 for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
4869 AE = FT->arg_type_end(); AI != AE; ++AI) {
4870 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
4871 Param->setScopeInfo(0, Params.size());
4872 Params.push_back(Param);
4873 }
David Blaikie9c70e042011-09-21 18:16:56 +00004874 NewFD->setParams(Params);
John McCall3e11ebe2010-03-15 10:12:16 +00004875 }
Ryan Flynn7d470f32009-07-30 03:15:39 +00004876 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
4877 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
Abramo Bagnaradff19302011-03-08 08:55:46 +00004878 VD->getInnerLocStart(), VD->getLocation(), II,
John McCallbcd03502009-12-07 02:54:59 +00004879 VD->getType(), VD->getTypeSourceInfo(),
Douglas Gregorc4df4072010-04-19 22:54:31 +00004880 VD->getStorageClass(),
4881 VD->getStorageClassAsWritten());
John McCall3e11ebe2010-03-15 10:12:16 +00004882 if (VD->getQualifier()) {
4883 VarDecl *NewVD = cast<VarDecl>(NewD);
Douglas Gregor14454802011-02-25 02:25:35 +00004884 NewVD->setQualifierInfo(VD->getQualifierLoc());
John McCall3e11ebe2010-03-15 10:12:16 +00004885 }
Ryan Flynn7d470f32009-07-30 03:15:39 +00004886 }
4887 return NewD;
4888}
4889
James Dennett634962f2012-06-14 21:40:34 +00004890/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak
Ryan Flynn7d470f32009-07-30 03:15:39 +00004891/// applied to it, possibly with an alias.
Ryan Flynnd963a492009-07-31 02:52:19 +00004892void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
Chris Lattnere6eab982009-09-08 18:10:11 +00004893 if (W.getUsed()) return; // only do this once
4894 W.setUsed(true);
4895 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
4896 IdentifierInfo *NDId = ND->getIdentifier();
Eli Friedmance3e2c82011-09-07 04:05:06 +00004897 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
Alexis Huntdcfba7b2010-08-18 23:23:40 +00004898 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
4899 NDId->getName()));
4900 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
Chris Lattnere6eab982009-09-08 18:10:11 +00004901 WeakTopLevelDecl.push_back(NewD);
4902 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
4903 // to insert Decl at TU scope, sorry.
4904 DeclContext *SavedContext = CurContext;
4905 CurContext = Context.getTranslationUnitDecl();
4906 PushOnScopeChains(NewD, S);
4907 CurContext = SavedContext;
4908 } else { // just add weak to existing
Alexis Huntdcfba7b2010-08-18 23:23:40 +00004909 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
Ryan Flynn7d470f32009-07-30 03:15:39 +00004910 }
4911}
4912
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004913/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
4914/// it, apply them to D. This is a bit tricky because PD can have attributes
4915/// specified in many different places, and we need to find and apply them all.
Peter Collingbourneb331b262011-01-21 02:08:45 +00004916void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
4917 bool NonInheritable, bool Inheritable) {
John McCall6fe02402010-10-27 00:59:00 +00004918 // It's valid to "forward-declare" #pragma weak, in which case we
4919 // have to do this.
Douglas Gregor1c4bfe52011-07-28 18:09:57 +00004920 if (Inheritable) {
4921 LoadExternalWeakUndeclaredIdentifiers();
4922 if (!WeakUndeclaredIdentifiers.empty()) {
4923 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
4924 if (IdentifierInfo *Id = ND->getIdentifier()) {
4925 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
4926 = WeakUndeclaredIdentifiers.find(Id);
4927 if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
4928 WeakInfo W = I->second;
4929 DeclApplyPragmaWeak(S, ND, W);
4930 WeakUndeclaredIdentifiers[Id] = W;
4931 }
John McCall6fe02402010-10-27 00:59:00 +00004932 }
Ryan Flynn7d470f32009-07-30 03:15:39 +00004933 }
4934 }
4935 }
4936
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004937 // Apply decl attributes from the DeclSpec if present.
John McCall53fa7142010-12-24 02:08:15 +00004938 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
Peter Collingbourneb331b262011-01-21 02:08:45 +00004939 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
Mike Stumpd3bb5572009-07-24 19:02:52 +00004940
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004941 // Walk the declarator structure, applying decl attributes that were in a type
4942 // position to the decl itself. This handles cases like:
4943 // int *__attr__(x)** D;
4944 // when X is a decl attribute.
4945 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
4946 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
Richard Smith10876ef2013-01-17 01:30:42 +00004947 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable,
4948 /*IncludeCXX11Attributes=*/false);
Mike Stumpd3bb5572009-07-24 19:02:52 +00004949
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004950 // Finally, apply any attributes on the decl itself.
4951 if (const AttributeList *Attrs = PD.getAttributes())
Peter Collingbourneb331b262011-01-21 02:08:45 +00004952 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
Chris Lattner9e2aafe2008-06-29 00:23:49 +00004953}
John McCall28a6aea2009-11-04 02:18:39 +00004954
John McCall31168b02011-06-15 23:02:42 +00004955/// Is the given declaration allowed to use a forbidden type?
4956static bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
4957 // Private ivars are always okay. Unfortunately, people don't
4958 // always properly make their ivars private, even in system headers.
4959 // Plus we need to make fields okay, too.
Fariborz Jahanian6d5d6a22011-09-26 21:23:35 +00004960 // Function declarations in sys headers will be marked unavailable.
4961 if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
4962 !isa<FunctionDecl>(decl))
John McCall31168b02011-06-15 23:02:42 +00004963 return false;
4964
4965 // Require it to be declared in a system header.
4966 return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
4967}
4968
4969/// Handle a delayed forbidden-type diagnostic.
4970static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
4971 Decl *decl) {
4972 if (decl && isForbiddenTypeAllowed(S, decl)) {
4973 decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
4974 "this system declaration uses an unsupported type"));
4975 return;
4976 }
David Blaikiebbafb8a2012-03-11 07:00:24 +00004977 if (S.getLangOpts().ObjCAutoRefCount)
Fariborz Jahanianed1933b2011-10-03 22:11:57 +00004978 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
Benjamin Kramer474261a2012-06-02 10:20:41 +00004979 // FIXME: we may want to suppress diagnostics for all
Fariborz Jahanianed1933b2011-10-03 22:11:57 +00004980 // kind of forbidden type messages on unavailable functions.
4981 if (FD->hasAttr<UnavailableAttr>() &&
4982 diag.getForbiddenTypeDiagnostic() ==
4983 diag::err_arc_array_param_no_ownership) {
4984 diag.Triggered = true;
4985 return;
4986 }
4987 }
John McCall31168b02011-06-15 23:02:42 +00004988
4989 S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
4990 << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
4991 diag.Triggered = true;
4992}
4993
John McCall2ec85372012-05-07 06:16:41 +00004994void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
4995 assert(DelayedDiagnostics.getCurrentPool());
John McCall6347b682012-05-07 06:16:58 +00004996 DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
John McCall2ec85372012-05-07 06:16:41 +00004997 DelayedDiagnostics.popWithoutEmitting(state);
John McCallc1465822011-02-14 07:13:47 +00004998
John McCall2ec85372012-05-07 06:16:41 +00004999 // When delaying diagnostics to run in the context of a parsed
5000 // declaration, we only want to actually emit anything if parsing
5001 // succeeds.
5002 if (!decl) return;
John McCallc1465822011-02-14 07:13:47 +00005003
John McCall2ec85372012-05-07 06:16:41 +00005004 // We emit all the active diagnostics in this pool or any of its
5005 // parents. In general, we'll get one pool for the decl spec
5006 // and a child pool for each declarator; in a decl group like:
5007 // deprecated_typedef foo, *bar, baz();
5008 // only the declarator pops will be passed decls. This is correct;
5009 // we really do need to consider delayed diagnostics from the decl spec
5010 // for each of the different declarations.
John McCall6347b682012-05-07 06:16:58 +00005011 const DelayedDiagnosticPool *pool = &poppedPool;
John McCall2ec85372012-05-07 06:16:41 +00005012 do {
John McCall6347b682012-05-07 06:16:58 +00005013 for (DelayedDiagnosticPool::pool_iterator
John McCall2ec85372012-05-07 06:16:41 +00005014 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
5015 // This const_cast is a bit lame. Really, Triggered should be mutable.
5016 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
John McCallc1465822011-02-14 07:13:47 +00005017 if (diag.Triggered)
John McCall86121512010-01-27 03:50:35 +00005018 continue;
5019
John McCallc1465822011-02-14 07:13:47 +00005020 switch (diag.Kind) {
John McCall86121512010-01-27 03:50:35 +00005021 case DelayedDiagnostic::Deprecation:
John McCall18a962b2012-01-26 20:04:03 +00005022 // Don't bother giving deprecation diagnostics if the decl is invalid.
5023 if (!decl->isInvalidDecl())
John McCall2ec85372012-05-07 06:16:41 +00005024 HandleDelayedDeprecationCheck(diag, decl);
John McCall86121512010-01-27 03:50:35 +00005025 break;
5026
5027 case DelayedDiagnostic::Access:
John McCall2ec85372012-05-07 06:16:41 +00005028 HandleDelayedAccessCheck(diag, decl);
John McCall86121512010-01-27 03:50:35 +00005029 break;
John McCall31168b02011-06-15 23:02:42 +00005030
5031 case DelayedDiagnostic::ForbiddenType:
John McCall2ec85372012-05-07 06:16:41 +00005032 handleDelayedForbiddenType(*this, diag, decl);
John McCall31168b02011-06-15 23:02:42 +00005033 break;
John McCall86121512010-01-27 03:50:35 +00005034 }
5035 }
John McCall2ec85372012-05-07 06:16:41 +00005036 } while ((pool = pool->getParent()));
John McCall28a6aea2009-11-04 02:18:39 +00005037}
5038
John McCall6347b682012-05-07 06:16:58 +00005039/// Given a set of delayed diagnostics, re-emit them as if they had
5040/// been delayed in the current context instead of in the given pool.
5041/// Essentially, this just moves them to the current pool.
5042void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
5043 DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
5044 assert(curPool && "re-emitting in undelayed context not supported");
5045 curPool->steal(pool);
5046}
5047
John McCall28a6aea2009-11-04 02:18:39 +00005048static bool isDeclDeprecated(Decl *D) {
5049 do {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00005050 if (D->isDeprecated())
John McCall28a6aea2009-11-04 02:18:39 +00005051 return true;
Argyrios Kyrtzidisc281c962011-10-06 23:23:27 +00005052 // A category implicitly has the availability of the interface.
5053 if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
5054 return CatD->getClassInterface()->isDeprecated();
John McCall28a6aea2009-11-04 02:18:39 +00005055 } while ((D = cast_or_null<Decl>(D->getDeclContext())));
5056 return false;
5057}
5058
Eli Friedman971bfa12012-08-08 21:52:41 +00005059static void
5060DoEmitDeprecationWarning(Sema &S, const NamedDecl *D, StringRef Message,
5061 SourceLocation Loc,
Fariborz Jahanian974c9482012-09-21 20:46:37 +00005062 const ObjCInterfaceDecl *UnknownObjCClass,
5063 const ObjCPropertyDecl *ObjCPropery) {
Eli Friedman971bfa12012-08-08 21:52:41 +00005064 DeclarationName Name = D->getDeclName();
5065 if (!Message.empty()) {
5066 S.Diag(Loc, diag::warn_deprecated_message) << Name << Message;
5067 S.Diag(D->getLocation(),
5068 isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
5069 : diag::note_previous_decl) << Name;
Fariborz Jahanian974c9482012-09-21 20:46:37 +00005070 if (ObjCPropery)
5071 S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute)
5072 << ObjCPropery->getDeclName() << 0;
Eli Friedman971bfa12012-08-08 21:52:41 +00005073 } else if (!UnknownObjCClass) {
5074 S.Diag(Loc, diag::warn_deprecated) << D->getDeclName();
5075 S.Diag(D->getLocation(),
5076 isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
5077 : diag::note_previous_decl) << Name;
Fariborz Jahanian974c9482012-09-21 20:46:37 +00005078 if (ObjCPropery)
5079 S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute)
5080 << ObjCPropery->getDeclName() << 0;
Eli Friedman971bfa12012-08-08 21:52:41 +00005081 } else {
5082 S.Diag(Loc, diag::warn_deprecated_fwdclass_message) << Name;
5083 S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
5084 }
5085}
5086
John McCallb45a1e72010-08-26 02:13:20 +00005087void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
John McCall86121512010-01-27 03:50:35 +00005088 Decl *Ctx) {
5089 if (isDeclDeprecated(Ctx))
John McCall28a6aea2009-11-04 02:18:39 +00005090 return;
5091
John McCall86121512010-01-27 03:50:35 +00005092 DD.Triggered = true;
Eli Friedman971bfa12012-08-08 21:52:41 +00005093 DoEmitDeprecationWarning(*this, DD.getDeprecationDecl(),
5094 DD.getDeprecationMessage(), DD.Loc,
Fariborz Jahanian974c9482012-09-21 20:46:37 +00005095 DD.getUnknownObjCClass(),
5096 DD.getObjCProperty());
John McCall28a6aea2009-11-04 02:18:39 +00005097}
5098
Chris Lattner0e62c1c2011-07-23 10:55:15 +00005099void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
Fariborz Jahanian7d6e11a2010-12-21 00:44:01 +00005100 SourceLocation Loc,
Fariborz Jahanian974c9482012-09-21 20:46:37 +00005101 const ObjCInterfaceDecl *UnknownObjCClass,
5102 const ObjCPropertyDecl *ObjCProperty) {
John McCall28a6aea2009-11-04 02:18:39 +00005103 // Delay if we're currently parsing a declaration.
John McCallc1465822011-02-14 07:13:47 +00005104 if (DelayedDiagnostics.shouldDelayDiagnostics()) {
Fariborz Jahanian7923ef42012-03-02 21:50:02 +00005105 DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
5106 UnknownObjCClass,
Fariborz Jahanian974c9482012-09-21 20:46:37 +00005107 ObjCProperty,
Fariborz Jahanian7923ef42012-03-02 21:50:02 +00005108 Message));
John McCall28a6aea2009-11-04 02:18:39 +00005109 return;
5110 }
5111
5112 // Otherwise, don't warn if our current context is deprecated.
Argyrios Kyrtzidis9321ad32011-10-06 23:23:20 +00005113 if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
John McCall28a6aea2009-11-04 02:18:39 +00005114 return;
Fariborz Jahanian974c9482012-09-21 20:46:37 +00005115 DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass, ObjCProperty);
John McCall28a6aea2009-11-04 02:18:39 +00005116}