blob: cb6e898020ce03bfe79c8e437d98f278ab3d9711 [file] [log] [blame]
Chris Lattner6b6b5372008-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 McCall2d887082010-08-25 22:03:47 +000014#include "clang/Sema/SemaInternal.h"
Anton Korobeynikov82d0a412010-01-10 12:58:08 +000015#include "TargetAttributesSema.h"
Chris Lattner6b6b5372008-06-26 18:38:35 +000016#include "clang/AST/ASTContext.h"
DeLesley Hutchinsbbba25f2012-05-04 16:28:38 +000017#include "clang/AST/CXXInheritance.h"
John McCall384aff82010-08-25 07:42:41 +000018#include "clang/AST/DeclCXX.h"
Daniel Dunbaracc5f3e2008-08-11 06:23:49 +000019#include "clang/AST/DeclObjC.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000020#include "clang/AST/DeclTemplate.h"
Daniel Dunbaracc5f3e2008-08-11 06:23:49 +000021#include "clang/AST/Expr.h"
John McCallf85e1932011-06-15 23:02:42 +000022#include "clang/Basic/SourceManager.h"
Chris Lattnerfbf13472008-06-27 22:18:37 +000023#include "clang/Basic/TargetInfo.h"
John McCall19510852010-08-20 18:27:03 +000024#include "clang/Sema/DeclSpec.h"
John McCall9c3087b2010-08-26 02:13:20 +000025#include "clang/Sema/DelayedDiagnostic.h"
John McCallfe98da02011-09-29 07:17:38 +000026#include "clang/Sema/Lookup.h"
Richard Smith3a2b7a12013-01-28 22:42:45 +000027#include "clang/Sema/Scope.h"
Chris Lattner797c3c42009-08-10 19:03:04 +000028#include "llvm/ADT/StringExtras.h"
Chris Lattner6b6b5372008-06-26 18:38:35 +000029using namespace clang;
John McCall9c3087b2010-08-26 02:13:20 +000030using namespace sema;
Chris Lattner6b6b5372008-06-26 18:38:35 +000031
John McCall883cc2c2011-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 Sadowskib51e0312011-08-09 17:59:31 +000034enum AttributeDeclKind {
John McCall883cc2c2011-03-02 12:29:23 +000035 ExpectedFunction,
36 ExpectedUnion,
37 ExpectedVariableOrFunction,
38 ExpectedFunctionOrMethod,
39 ExpectedParameter,
John McCall883cc2c2011-03-02 12:29:23 +000040 ExpectedFunctionMethodOrBlock,
Kaelyn Uhrain51ceb7b2012-11-12 23:48:05 +000041 ExpectedFunctionMethodOrClass,
John McCall883cc2c2011-03-02 12:29:23 +000042 ExpectedFunctionMethodOrParameter,
43 ExpectedClass,
John McCall883cc2c2011-03-02 12:29:23 +000044 ExpectedVariable,
45 ExpectedMethod,
Caitlin Sadowskidb33e142011-07-28 20:12:35 +000046 ExpectedVariableFunctionOrLabel,
Douglas Gregorf6b8b582012-03-14 16:55:17 +000047 ExpectedFieldOrGlobalVar,
Hans Wennborg5e2d5de2012-06-23 11:51:46 +000048 ExpectedStruct,
Kaelyn Uhrain51ceb7b2012-11-12 23:48:05 +000049 ExpectedVariableFunctionOrTag,
Hans Wennborg5e2d5de2012-06-23 11:51:46 +000050 ExpectedTLSVar
John McCall883cc2c2011-03-02 12:29:23 +000051};
52
Chris Lattnere5c5ee12008-06-29 00:16:31 +000053//===----------------------------------------------------------------------===//
54// Helper functions
55//===----------------------------------------------------------------------===//
56
Chandler Carruth87c44602011-07-01 23:49:12 +000057static const FunctionType *getFunctionType(const Decl *D,
Ted Kremeneka18d7d82009-08-14 20:49:40 +000058 bool blocksToo = true) {
Chris Lattner6b6b5372008-06-26 18:38:35 +000059 QualType Ty;
Chandler Carruth87c44602011-07-01 23:49:12 +000060 if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
Chris Lattner6b6b5372008-06-26 18:38:35 +000061 Ty = decl->getType();
Chandler Carruth87c44602011-07-01 23:49:12 +000062 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
Chris Lattner6b6b5372008-06-26 18:38:35 +000063 Ty = decl->getType();
Chandler Carruth87c44602011-07-01 23:49:12 +000064 else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
Chris Lattner6b6b5372008-06-26 18:38:35 +000065 Ty = decl->getUnderlyingType();
66 else
67 return 0;
Mike Stumpbf916502009-07-24 19:02:52 +000068
Chris Lattner6b6b5372008-06-26 18:38:35 +000069 if (Ty->isFunctionPointerType())
Ted Kremenek6217b802009-07-29 21:53:49 +000070 Ty = Ty->getAs<PointerType>()->getPointeeType();
Fariborz Jahanian755f9d22009-05-18 17:39:25 +000071 else if (blocksToo && Ty->isBlockPointerType())
Ted Kremenek6217b802009-07-29 21:53:49 +000072 Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
Daniel Dunbard3f2c102008-10-19 02:04:16 +000073
John McCall183700f2009-09-21 23:43:11 +000074 return Ty->getAs<FunctionType>();
Chris Lattner6b6b5372008-06-26 18:38:35 +000075}
76
Daniel Dunbar35682492008-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 Lopesd20254f2009-12-20 23:11:08 +000080/// isFunction - Return true if the given decl has function
Ted Kremeneka18d7d82009-08-14 20:49:40 +000081/// type (function or function-typed variable).
Chandler Carruth87c44602011-07-01 23:49:12 +000082static bool isFunction(const Decl *D) {
83 return getFunctionType(D, false) != NULL;
Ted Kremeneka18d7d82009-08-14 20:49:40 +000084}
85
86/// isFunctionOrMethod - Return true if the given decl has function
Daniel Dunbard3f2c102008-10-19 02:04:16 +000087/// type (function or function-typed variable) or an Objective-C
88/// method.
Chandler Carruth87c44602011-07-01 23:49:12 +000089static bool isFunctionOrMethod(const Decl *D) {
Nick Lewycky4ae89bc2012-07-24 01:31:55 +000090 return isFunction(D) || isa<ObjCMethodDecl>(D);
Daniel Dunbar35682492008-09-26 04:12:28 +000091}
92
Fariborz Jahanian620d89c2009-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 Carruth87c44602011-07-01 23:49:12 +000096static bool isFunctionOrMethodOrBlock(const Decl *D) {
97 if (isFunctionOrMethod(D))
Fariborz Jahanian620d89c2009-05-15 23:15:03 +000098 return true;
99 // check for block is more involved.
Chandler Carruth87c44602011-07-01 23:49:12 +0000100 if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
Fariborz Jahanian620d89c2009-05-15 23:15:03 +0000101 QualType Ty = V->getType();
102 return Ty->isBlockPointerType();
103 }
Chandler Carruth87c44602011-07-01 23:49:12 +0000104 return isa<BlockDecl>(D);
Fariborz Jahanian620d89c2009-05-15 23:15:03 +0000105}
106
John McCall711c52b2011-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 Carruth87c44602011-07-01 23:49:12 +0000109static bool hasDeclarator(const Decl *D) {
John McCallf85e1932011-06-15 23:02:42 +0000110 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
Chandler Carruth87c44602011-07-01 23:49:12 +0000111 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
112 isa<ObjCPropertyDecl>(D);
John McCall711c52b2011-01-05 12:14:39 +0000113}
114
Daniel Dunbard3f2c102008-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 Jahanian620d89c2009-05-15 23:15:03 +0000117/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
Chandler Carruth87c44602011-07-01 23:49:12 +0000118static bool hasFunctionProto(const Decl *D) {
119 if (const FunctionType *FnTy = getFunctionType(D))
Douglas Gregor72564e72009-02-26 23:50:07 +0000120 return isa<FunctionProtoType>(FnTy);
Fariborz Jahanian620d89c2009-05-15 23:15:03 +0000121 else {
Chandler Carruth87c44602011-07-01 23:49:12 +0000122 assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
Daniel Dunbard3f2c102008-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 Carruth87c44602011-07-01 23:49:12 +0000130static unsigned getFunctionOrMethodNumArgs(const Decl *D) {
131 if (const FunctionType *FnTy = getFunctionType(D))
Douglas Gregor72564e72009-02-26 23:50:07 +0000132 return cast<FunctionProtoType>(FnTy)->getNumArgs();
Chandler Carruth87c44602011-07-01 23:49:12 +0000133 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
Fariborz Jahaniand66f22d2009-05-19 17:08:59 +0000134 return BD->getNumParams();
Chandler Carruth87c44602011-07-01 23:49:12 +0000135 return cast<ObjCMethodDecl>(D)->param_size();
Daniel Dunbar35682492008-09-26 04:12:28 +0000136}
137
Chandler Carruth87c44602011-07-01 23:49:12 +0000138static QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
139 if (const FunctionType *FnTy = getFunctionType(D))
Douglas Gregor72564e72009-02-26 23:50:07 +0000140 return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
Chandler Carruth87c44602011-07-01 23:49:12 +0000141 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
Fariborz Jahaniand66f22d2009-05-19 17:08:59 +0000142 return BD->getParamDecl(Idx)->getType();
Mike Stumpbf916502009-07-24 19:02:52 +0000143
Chandler Carruth87c44602011-07-01 23:49:12 +0000144 return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
Daniel Dunbar35682492008-09-26 04:12:28 +0000145}
146
Chandler Carruth87c44602011-07-01 23:49:12 +0000147static QualType getFunctionOrMethodResultType(const Decl *D) {
148 if (const FunctionType *FnTy = getFunctionType(D))
Fariborz Jahanian5b160922009-05-20 17:41:43 +0000149 return cast<FunctionProtoType>(FnTy)->getResultType();
Chandler Carruth87c44602011-07-01 23:49:12 +0000150 return cast<ObjCMethodDecl>(D)->getResultType();
Fariborz Jahanian5b160922009-05-20 17:41:43 +0000151}
152
Chandler Carruth87c44602011-07-01 23:49:12 +0000153static bool isFunctionOrMethodVariadic(const Decl *D) {
154 if (const FunctionType *FnTy = getFunctionType(D)) {
Douglas Gregor72564e72009-02-26 23:50:07 +0000155 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
Daniel Dunbar35682492008-09-26 04:12:28 +0000156 return proto->isVariadic();
Chandler Carruth87c44602011-07-01 23:49:12 +0000157 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
Ted Kremenekdb9a0ae2010-04-29 16:48:58 +0000158 return BD->isVariadic();
Fariborz Jahaniand66f22d2009-05-19 17:08:59 +0000159 else {
Chandler Carruth87c44602011-07-01 23:49:12 +0000160 return cast<ObjCMethodDecl>(D)->isVariadic();
Daniel Dunbar35682492008-09-26 04:12:28 +0000161 }
162}
163
Chandler Carruth87c44602011-07-01 23:49:12 +0000164static bool isInstanceMethod(const Decl *D) {
165 if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
Chandler Carruth07d7e7a2010-11-16 08:35:43 +0000166 return MethodDecl->isInstance();
167 return false;
168}
169
Chris Lattner6b6b5372008-06-26 18:38:35 +0000170static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
John McCall183700f2009-09-21 23:43:11 +0000171 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
Chris Lattnerb77792e2008-07-26 22:17:49 +0000172 if (!PT)
Chris Lattner6b6b5372008-06-26 18:38:35 +0000173 return false;
Mike Stumpbf916502009-07-24 19:02:52 +0000174
John McCall506b57e2010-05-17 21:00:27 +0000175 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
176 if (!Cls)
Chris Lattner6b6b5372008-06-26 18:38:35 +0000177 return false;
Mike Stumpbf916502009-07-24 19:02:52 +0000178
John McCall506b57e2010-05-17 21:00:27 +0000179 IdentifierInfo* ClsName = Cls->getIdentifier();
Mike Stumpbf916502009-07-24 19:02:52 +0000180
Chris Lattner6b6b5372008-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 Dunbar085e8f72008-09-26 03:32:58 +0000186static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
Ted Kremenek6217b802009-07-29 21:53:49 +0000187 const PointerType *PT = T->getAs<PointerType>();
Daniel Dunbar085e8f72008-09-26 03:32:58 +0000188 if (!PT)
189 return false;
190
Ted Kremenek6217b802009-07-29 21:53:49 +0000191 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
Daniel Dunbar085e8f72008-09-26 03:32:58 +0000192 if (!RT)
193 return false;
Mike Stumpbf916502009-07-24 19:02:52 +0000194
Daniel Dunbar085e8f72008-09-26 03:32:58 +0000195 const RecordDecl *RD = RT->getDecl();
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000196 if (RD->getTagKind() != TTK_Struct)
Daniel Dunbar085e8f72008-09-26 03:32:58 +0000197 return false;
198
199 return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
200}
201
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000202/// \brief Check if the attribute has exactly as many args as Num. May
203/// output an error.
Chandler Carruth1731e202011-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 Sadowskidb33e142011-07-28 20:12:35 +0000214
Caitlin Sadowskib51e0312011-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 Sadowskidb33e142011-07-28 20:12:35 +0000220 S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
221 return false;
222 }
223
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000224 return true;
225}
226
Dmitri Gribenko0d5a0692012-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 Sadowskidb33e142011-07-28 20:12:35 +0000274///
Caitlin Sadowskifdde9e72011-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 Kramer39997fc2011-08-02 04:50:49 +0000278static bool mayBeSharedVariable(const Decl *D) {
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000279 if (isa<FieldDecl>(D))
280 return true;
Benjamin Kramer39997fc2011-08-02 04:50:49 +0000281 if (const VarDecl *vd = dyn_cast<VarDecl>(D))
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000282 return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
283
284 return false;
285}
286
Caitlin Sadowskib51e0312011-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 Hutchinsaed9ea32012-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 Hutchins60f20242012-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 Blaikie3bc93e32012-12-19 00:45:41 +0000299 if (Res1.empty())
DeLesley Hutchins60f20242012-05-02 22:18:42 +0000300 return false;
DeLesley Hutchinsaed9ea32012-04-23 18:39:55 +0000301
DeLesley Hutchins60f20242012-05-02 22:18:42 +0000302 DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
303 S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
David Blaikie3bc93e32012-12-19 00:45:41 +0000304 if (Res2.empty())
DeLesley Hutchins60f20242012-05-02 22:18:42 +0000305 return false;
306
307 return true;
DeLesley Hutchinsaed9ea32012-04-23 18:39:55 +0000308}
309
Caitlin Sadowskifdde9e72011-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 Hutchinsae519c42012-04-19 16:10:44 +0000313static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
314 const AttributeList &Attr) {
Benjamin Kramer39997fc2011-08-02 04:50:49 +0000315 if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000316 QualType QT = vd->getType();
Benjamin Kramer39997fc2011-08-02 04:50:49 +0000317 if (QT->isAnyPointerType())
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000318 return true;
DeLesley Hutchinsaed9ea32012-04-23 18:39:55 +0000319
DeLesley Hutchins60f20242012-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 Hutchinsaed9ea32012-04-23 18:39:55 +0000330
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000331 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
Caitlin Sadowskifdde9e72011-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 Sadowskib51e0312011-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 Kramer7d23b4a2011-08-19 04:18:11 +0000342static const RecordType *getRecordType(QualType QT) {
343 if (const RecordType *RT = QT->getAs<RecordType>())
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000344 return RT;
Benjamin Kramer7d23b4a2011-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 Sadowskib51e0312011-08-09 17:59:31 +0000351}
352
DeLesley Hutchinsbbba25f2012-05-04 16:28:38 +0000353
Jordy Rosefad5de92012-05-08 03:27:22 +0000354static bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier,
355 CXXBasePath &Path, void *Unused) {
DeLesley Hutchinsbbba25f2012-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 Sadowski3ac1fbc2011-08-23 18:46:34 +0000363/// \brief Thread Safety Analysis: Checks that the passed in RecordType
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000364/// resolves to a lockable object.
DeLesley Hutchins83cad452012-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 Hanf1aae3b2012-08-03 17:40:43 +0000368
DeLesley Hutchins83cad452012-04-06 20:02:30 +0000369 // Warn if could not get record type for this argument.
Benjamin Kramerd77ba892011-09-03 03:30:59 +0000370 if (!RT) {
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000371 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
DeLesley Hutchins83cad452012-04-06 20:02:30 +0000372 << Attr.getName() << Ty.getAsString();
373 return;
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000374 }
DeLesley Hutchins60f20242012-05-02 22:18:42 +0000375
Michael Hanf1aae3b2012-08-03 17:40:43 +0000376 // Don't check for lockable if the class hasn't been defined yet.
DeLesley Hutchins634b2932012-02-16 17:15:51 +0000377 if (RT->isIncompleteType())
DeLesley Hutchins83cad452012-04-06 20:02:30 +0000378 return;
DeLesley Hutchins60f20242012-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 Hutchinsbbba25f2012-05-04 16:28:38 +0000385 // Check if the type is lockable.
386 RecordDecl *RD = RT->getDecl();
387 if (RD->getAttr<LockableAttr>())
DeLesley Hutchins83cad452012-04-06 20:02:30 +0000388 return;
DeLesley Hutchinsbbba25f2012-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 Sadowski3ac1fbc2011-08-23 18:46:34 +0000395 }
DeLesley Hutchinsbbba25f2012-05-04 16:28:38 +0000396
397 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
398 << Attr.getName() << Ty.getAsString();
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000399}
400
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000401/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000402/// from Sidx, resolve to a lockable object.
Caitlin Sadowski3ac1fbc2011-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 Hutchinsae519c42012-04-19 16:10:44 +0000406static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000407 const AttributeList &Attr,
408 SmallVectorImpl<Expr*> &Args,
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000409 int Sidx = 0,
410 bool ParamIdxOk = false) {
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000411 for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000412 Expr *ArgExp = Attr.getArg(Idx);
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000413
Caitlin Sadowskied9d84a2011-09-08 17:42:31 +0000414 if (ArgExp->isTypeDependent()) {
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000415 // FIXME -- need to check this again on template instantiation
Caitlin Sadowskied9d84a2011-09-08 17:42:31 +0000416 Args.push_back(ArgExp);
417 continue;
418 }
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000419
DeLesley Hutchins79747e02012-04-23 16:45:01 +0000420 if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
DeLesley Hutchins0b4db3e2012-09-07 17:34:53 +0000421 if (StrLit->getLength() == 0 ||
422 StrLit->getString() == StringRef("*")) {
DeLesley Hutchins4e4c1572012-08-31 21:57:32 +0000423 // Pass empty strings to the analyzer without warnings.
DeLesley Hutchins0b4db3e2012-09-07 17:34:53 +0000424 // Treat "*" as the universal lock.
DeLesley Hutchins4e4c1572012-08-31 21:57:32 +0000425 Args.push_back(ArgExp);
DeLesley Hutchins79747e02012-04-23 16:45:01 +0000426 continue;
DeLesley Hutchins4e4c1572012-08-31 21:57:32 +0000427 }
DeLesley Hutchins79747e02012-04-23 16:45:01 +0000428
DeLesley Hutchinsae519c42012-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 Hutchins4e4c1572012-08-31 21:57:32 +0000433 Args.push_back(ArgExp);
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000434 continue;
435 }
436
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000437 QualType ArgTy = ArgExp->getType();
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000438
DeLesley Hutchins79747e02012-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 Sadowski3ac1fbc2011-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 Sadowskib51e0312011-08-09 17:59:31 +0000449
Caitlin Sadowski3ac1fbc2011-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 Sadowskib51e0312011-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 Sadowski3ac1fbc2011-08-23 18:46:34 +0000457 uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
458 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
459 if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000460 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
461 << Attr.getName() << Idx + 1 << NumParams;
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000462 continue;
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000463 }
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000464 ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000465 }
466 }
467
DeLesley Hutchins83cad452012-04-06 20:02:30 +0000468 checkForLockableRecord(S, D, Attr, ArgTy);
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000469
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000470 Args.push_back(ArgExp);
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000471 }
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000472}
473
Chris Lattnere5c5ee12008-06-29 00:16:31 +0000474//===----------------------------------------------------------------------===//
Chris Lattnere5c5ee12008-06-29 00:16:31 +0000475// Attribute Implementations
476//===----------------------------------------------------------------------===//
477
Daniel Dunbar3068ae02008-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 Hutchins0aa52aa2012-06-19 23:25:19 +0000482enum ThreadAttributeDeclKind {
483 ThreadExpectedFieldOrGlobalVar,
484 ThreadExpectedFunctionOrMethod,
485 ThreadExpectedClassOrStruct
486};
487
Michael Hanf1aae3b2012-08-03 17:40:43 +0000488static bool checkGuardedVarAttrCommon(Sema &S, Decl *D,
Michael Handc691572012-07-23 18:48:41 +0000489 const AttributeList &Attr) {
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000490 assert(!Attr.isInvalid());
491
492 if (!checkAttributeNumArgs(S, Attr, 0))
Michael Handc691572012-07-23 18:48:41 +0000493 return false;
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000494
495 // D must be either a member field or global (potentially shared) variable.
496 if (!mayBeSharedVariable(D)) {
DeLesley Hutchins0aa52aa2012-06-19 23:25:19 +0000497 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
498 << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
Michael Handc691572012-07-23 18:48:41 +0000499 return false;
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000500 }
501
Michael Handc691572012-07-23 18:48:41 +0000502 return true;
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000503}
504
Michael Handc691572012-07-23 18:48:41 +0000505static void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr) {
506 if (!checkGuardedVarAttrCommon(S, D, Attr))
507 return;
Michael Hanf1aae3b2012-08-03 17:40:43 +0000508
Michael Han51d8c522013-01-24 16:46:58 +0000509 D->addAttr(::new (S.Context)
510 GuardedVarAttr(Attr.getRange(), S.Context,
511 Attr.getAttributeSpellingListIndex()));
Michael Handc691572012-07-23 18:48:41 +0000512}
513
Michael Hanf1aae3b2012-08-03 17:40:43 +0000514static void handlePtGuardedVarAttr(Sema &S, Decl *D,
Michael Han51d8c522013-01-24 16:46:58 +0000515 const AttributeList &Attr) {
Michael Handc691572012-07-23 18:48:41 +0000516 if (!checkGuardedVarAttrCommon(S, D, Attr))
517 return;
518
519 if (!threadSafetyCheckIsPointer(S, D, Attr))
520 return;
521
Michael Han51d8c522013-01-24 16:46:58 +0000522 D->addAttr(::new (S.Context)
523 PtGuardedVarAttr(Attr.getRange(), S.Context,
524 Attr.getAttributeSpellingListIndex()));
Michael Handc691572012-07-23 18:48:41 +0000525}
526
Michael Hanf1aae3b2012-08-03 17:40:43 +0000527static bool checkGuardedByAttrCommon(Sema &S, Decl *D,
528 const AttributeList &Attr,
Michael Handc691572012-07-23 18:48:41 +0000529 Expr* &Arg) {
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000530 assert(!Attr.isInvalid());
531
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000532 if (!checkAttributeNumArgs(S, Attr, 1))
Michael Handc691572012-07-23 18:48:41 +0000533 return false;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000534
535 // D must be either a member field or global (potentially shared) variable.
536 if (!mayBeSharedVariable(D)) {
DeLesley Hutchins0aa52aa2012-06-19 23:25:19 +0000537 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
538 << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
Michael Handc691572012-07-23 18:48:41 +0000539 return false;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000540 }
541
DeLesley Hutchinsae519c42012-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 Handc691572012-07-23 18:48:41 +0000547 return false;
Michael Hanf1aae3b2012-08-03 17:40:43 +0000548
Michael Handc691572012-07-23 18:48:41 +0000549 Arg = Args[0];
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000550
Michael Handc691572012-07-23 18:48:41 +0000551 return true;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000552}
553
Michael Handc691572012-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 Sadowskidb33e142011-07-28 20:12:35 +0000558
Michael Handc691572012-07-23 18:48:41 +0000559 D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
560}
561
Michael Hanf1aae3b2012-08-03 17:40:43 +0000562static void handlePtGuardedByAttr(Sema &S, Decl *D,
Michael Handc691572012-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 Hanf1aae3b2012-08-03 17:40:43 +0000575static bool checkLockableAttrCommon(Sema &S, Decl *D,
Michael Handc691572012-07-23 18:48:41 +0000576 const AttributeList &Attr) {
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000577 assert(!Attr.isInvalid());
578
579 if (!checkAttributeNumArgs(S, Attr, 0))
Michael Handc691572012-07-23 18:48:41 +0000580 return false;
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000581
Caitlin Sadowski1748b122011-09-16 00:35:54 +0000582 // FIXME: Lockable structs for C code.
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000583 if (!isa<CXXRecordDecl>(D)) {
DeLesley Hutchins0aa52aa2012-06-19 23:25:19 +0000584 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
585 << Attr.getName() << ThreadExpectedClassOrStruct;
Michael Handc691572012-07-23 18:48:41 +0000586 return false;
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000587 }
588
Michael Handc691572012-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 Hanf1aae3b2012-08-03 17:40:43 +0000599static void handleScopedLockableAttr(Sema &S, Decl *D,
Michael Handc691572012-07-23 18:48:41 +0000600 const AttributeList &Attr) {
601 if (!checkLockableAttrCommon(S, D, Attr))
602 return;
603
Michael Han51d8c522013-01-24 16:46:58 +0000604 D->addAttr(::new (S.Context)
605 ScopedLockableAttr(Attr.getRange(), S.Context,
606 Attr.getAttributeSpellingListIndex()));
Caitlin Sadowskifdde9e72011-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 Sadowskib51e0312011-08-09 17:59:31 +0000616 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins0aa52aa2012-06-19 23:25:19 +0000617 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
618 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000619 return;
620 }
621
Argyrios Kyrtzidis768d6ca2011-09-13 16:05:58 +0000622 D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +0000623 S.Context));
624}
625
Kostya Serebryany71efba02012-01-24 19:25:38 +0000626static void handleNoAddressSafetyAttr(Sema &S, Decl *D,
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000627 const AttributeList &Attr) {
Kostya Serebryany71efba02012-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 Han51d8c522013-01-24 16:46:58 +0000639 D->addAttr(::new (S.Context)
640 NoAddressSafetyAnalysisAttr(Attr.getRange(), S.Context,
641 Attr.getAttributeSpellingListIndex()));
Kostya Serebryany71efba02012-01-24 19:25:38 +0000642}
643
Michael Hanf1aae3b2012-08-03 17:40:43 +0000644static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
645 const AttributeList &Attr,
Michael Handc691572012-07-23 18:48:41 +0000646 SmallVector<Expr*, 1> &Args) {
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000647 assert(!Attr.isInvalid());
648
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000649 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
Michael Handc691572012-07-23 18:48:41 +0000650 return false;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000651
652 // D must be either a member field or global (potentially shared) variable.
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000653 ValueDecl *VD = dyn_cast<ValueDecl>(D);
654 if (!VD || !mayBeSharedVariable(D)) {
DeLesley Hutchins0aa52aa2012-06-19 23:25:19 +0000655 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
656 << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
Michael Handc691572012-07-23 18:48:41 +0000657 return false;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000658 }
659
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000660 // Check that this attribute only applies to lockable types.
Caitlin Sadowskib51e0312011-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 Hutchinsae519c42012-04-19 16:10:44 +0000665 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
Michael Handc691572012-07-23 18:48:41 +0000666 << Attr.getName();
667 return false;
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000668 }
669 }
670
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000671 // Check that all arguments are lockable objects.
672 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
Michael Handc691572012-07-23 18:48:41 +0000673 if (Args.size() == 0)
674 return false;
Michael Hanf1aae3b2012-08-03 17:40:43 +0000675
Michael Handc691572012-07-23 18:48:41 +0000676 return true;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000677}
678
Michael Hanf1aae3b2012-08-03 17:40:43 +0000679static void handleAcquiredAfterAttr(Sema &S, Decl *D,
Michael Handc691572012-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 Han51d8c522013-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 Handc691572012-07-23 18:48:41 +0000690}
691
Michael Hanf1aae3b2012-08-03 17:40:43 +0000692static void handleAcquiredBeforeAttr(Sema &S, Decl *D,
Michael Handc691572012-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 Han51d8c522013-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 Handc691572012-07-23 18:48:41 +0000703}
704
Michael Hanf1aae3b2012-08-03 17:40:43 +0000705static bool checkLockFunAttrCommon(Sema &S, Decl *D,
706 const AttributeList &Attr,
Michael Handc691572012-07-23 18:48:41 +0000707 SmallVector<Expr*, 1> &Args) {
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000708 assert(!Attr.isInvalid());
709
710 // zero or more arguments ok
711
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000712 // check that the attribute is applied to a function
713 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins0aa52aa2012-06-19 23:25:19 +0000714 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
715 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Michael Handc691572012-07-23 18:48:41 +0000716 return false;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000717 }
718
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000719 // check that all arguments are lockable objects
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000720 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000721
Michael Handc691572012-07-23 18:48:41 +0000722 return true;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000723}
724
Michael Hanf1aae3b2012-08-03 17:40:43 +0000725static void handleSharedLockFunctionAttr(Sema &S, Decl *D,
Michael Handc691572012-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 Han51d8c522013-01-24 16:46:58 +0000733 D->addAttr(::new (S.Context)
734 SharedLockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
735 Attr.getAttributeSpellingListIndex()));
Michael Handc691572012-07-23 18:48:41 +0000736}
737
Michael Hanf1aae3b2012-08-03 17:40:43 +0000738static void handleExclusiveLockFunctionAttr(Sema &S, Decl *D,
Michael Handc691572012-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 Han51d8c522013-01-24 16:46:58 +0000746 D->addAttr(::new (S.Context)
747 ExclusiveLockFunctionAttr(Attr.getRange(), S.Context,
748 StartArg, Size,
749 Attr.getAttributeSpellingListIndex()));
Michael Handc691572012-07-23 18:48:41 +0000750}
751
Michael Hanf1aae3b2012-08-03 17:40:43 +0000752static bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
753 const AttributeList &Attr,
Michael Handc691572012-07-23 18:48:41 +0000754 SmallVector<Expr*, 2> &Args) {
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000755 assert(!Attr.isInvalid());
756
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000757 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
Michael Handc691572012-07-23 18:48:41 +0000758 return false;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000759
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000760 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins0aa52aa2012-06-19 23:25:19 +0000761 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
762 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Michael Handc691572012-07-23 18:48:41 +0000763 return false;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000764 }
765
Caitlin Sadowskib51e0312011-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 Handc691572012-07-23 18:48:41 +0000768 << Attr.getName();
769 return false;
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000770 }
771
772 // check that all arguments are lockable objects
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000773 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000774
Michael Handc691572012-07-23 18:48:41 +0000775 return true;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000776}
777
Michael Hanf1aae3b2012-08-03 17:40:43 +0000778static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
Michael Handc691572012-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 Han51d8c522013-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 Handc691572012-07-23 18:48:41 +0000790}
791
Michael Hanf1aae3b2012-08-03 17:40:43 +0000792static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
Michael Handc691572012-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 Han51d8c522013-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 Handc691572012-07-23 18:48:41 +0000804}
805
Michael Hanf1aae3b2012-08-03 17:40:43 +0000806static bool checkLocksRequiredCommon(Sema &S, Decl *D,
807 const AttributeList &Attr,
Michael Handc691572012-07-23 18:48:41 +0000808 SmallVector<Expr*, 1> &Args) {
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000809 assert(!Attr.isInvalid());
810
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000811 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
Michael Handc691572012-07-23 18:48:41 +0000812 return false;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000813
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000814 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins0aa52aa2012-06-19 23:25:19 +0000815 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
816 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Michael Handc691572012-07-23 18:48:41 +0000817 return false;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000818 }
819
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000820 // check that all arguments are lockable objects
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000821 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
Michael Handc691572012-07-23 18:48:41 +0000822 if (Args.size() == 0)
823 return false;
Michael Hanf1aae3b2012-08-03 17:40:43 +0000824
Michael Handc691572012-07-23 18:48:41 +0000825 return true;
826}
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000827
Michael Hanf1aae3b2012-08-03 17:40:43 +0000828static void handleExclusiveLocksRequiredAttr(Sema &S, Decl *D,
Michael Handc691572012-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 Han51d8c522013-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 Handc691572012-07-23 18:48:41 +0000839}
840
Michael Hanf1aae3b2012-08-03 17:40:43 +0000841static void handleSharedLocksRequiredAttr(Sema &S, Decl *D,
Michael Handc691572012-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 Han51d8c522013-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 Sadowskidb33e142011-07-28 20:12:35 +0000852}
853
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000854static void handleUnlockFunAttr(Sema &S, Decl *D,
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000855 const AttributeList &Attr) {
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000856 assert(!Attr.isInvalid());
857
858 // zero or more arguments ok
859
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000860 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins0aa52aa2012-06-19 23:25:19 +0000861 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
862 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000863 return;
864 }
865
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000866 // check that all arguments are lockable objects
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000867 SmallVector<Expr*, 1> Args;
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000868 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000869 unsigned Size = Args.size();
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000870 Expr **StartArg = Size == 0 ? 0 : &Args[0];
871
Michael Han51d8c522013-01-24 16:46:58 +0000872 D->addAttr(::new (S.Context)
873 UnlockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
874 Attr.getAttributeSpellingListIndex()));
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000875}
876
877static void handleLockReturnedAttr(Sema &S, Decl *D,
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000878 const AttributeList &Attr) {
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000879 assert(!Attr.isInvalid());
880
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000881 if (!checkAttributeNumArgs(S, Attr, 1))
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000882 return;
883
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000884 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins0aa52aa2012-06-19 23:25:19 +0000885 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
886 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000887 return;
888 }
889
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000890 // check that the argument is lockable object
DeLesley Hutchinsf26efd72012-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 Sadowski3ac1fbc2011-08-23 18:46:34 +0000896
Michael Han51d8c522013-01-24 16:46:58 +0000897 D->addAttr(::new (S.Context)
898 LockReturnedAttr(Attr.getRange(), S.Context, Args[0],
899 Attr.getAttributeSpellingListIndex()));
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000900}
901
902static void handleLocksExcludedAttr(Sema &S, Decl *D,
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000903 const AttributeList &Attr) {
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000904 assert(!Attr.isInvalid());
905
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000906 if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000907 return;
908
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000909 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
DeLesley Hutchins0aa52aa2012-06-19 23:25:19 +0000910 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
911 << Attr.getName() << ThreadExpectedFunctionOrMethod;
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000912 return;
913 }
914
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000915 // check that all arguments are lockable objects
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000916 SmallVector<Expr*, 1> Args;
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000917 checkAttrArgsAreLockableObjs(S, D, Attr, Args);
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000918 unsigned Size = Args.size();
DeLesley Hutchinsae519c42012-04-19 16:10:44 +0000919 if (Size == 0)
920 return;
921 Expr **StartArg = &Args[0];
Caitlin Sadowski3ac1fbc2011-08-23 18:46:34 +0000922
Michael Han51d8c522013-01-24 16:46:58 +0000923 D->addAttr(::new (S.Context)
924 LocksExcludedAttr(Attr.getRange(), S.Context, StartArg, Size,
925 Attr.getAttributeSpellingListIndex()));
Caitlin Sadowskidb33e142011-07-28 20:12:35 +0000926}
927
928
Chandler Carruth1b03c872011-07-02 00:01:44 +0000929static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
930 const AttributeList &Attr) {
Richard Smitha4fa9002013-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 Lattner803d0802008-06-29 00:43:07 +0000935 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
Chris Lattner545dd342008-06-28 23:36:30 +0000936 return;
Chris Lattner6b6b5372008-06-26 18:38:35 +0000937 }
Mike Stumpbf916502009-07-24 19:02:52 +0000938
Richard Smitha4fa9002013-01-13 02:11:23 +0000939 // Remember this typedef decl, we will need it later for diagnostics.
940 S.ExtVectorDecls.push_back(TD);
Chris Lattner6b6b5372008-06-26 18:38:35 +0000941}
942
Chandler Carruth1b03c872011-07-02 00:01:44 +0000943static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner6b6b5372008-06-26 18:38:35 +0000944 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +0000945 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattner6b6b5372008-06-26 18:38:35 +0000946 return;
Mike Stumpbf916502009-07-24 19:02:52 +0000947
Chandler Carruth87c44602011-07-01 23:49:12 +0000948 if (TagDecl *TD = dyn_cast<TagDecl>(D))
Argyrios Kyrtzidis768d6ca2011-09-13 16:05:58 +0000949 TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
Chandler Carruth87c44602011-07-01 23:49:12 +0000950 else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
Chris Lattner6b6b5372008-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 Friedmanb68ec6b2012-11-07 00:35:20 +0000953 if (!FD->getType()->isDependentType() &&
954 !FD->getType()->isIncompleteType() &&
Chris Lattner803d0802008-06-29 00:43:07 +0000955 S.Context.getTypeAlign(FD->getType()) <= 8)
Chris Lattnerfa25bbb2008-11-19 05:08:23 +0000956 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
Chris Lattner08631c52008-11-23 21:45:46 +0000957 << Attr.getName() << FD->getType();
Chris Lattner6b6b5372008-06-26 18:38:35 +0000958 else
Michael Han51d8c522013-01-24 16:46:58 +0000959 FD->addAttr(::new (S.Context)
960 PackedAttr(Attr.getRange(), S.Context,
961 Attr.getAttributeSpellingListIndex()));
Chris Lattner6b6b5372008-06-26 18:38:35 +0000962 } else
Chris Lattner3c73c412008-11-19 08:23:25 +0000963 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
Chris Lattner6b6b5372008-06-26 18:38:35 +0000964}
965
Chandler Carruth1b03c872011-07-02 00:01:44 +0000966static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Eli Friedman5f608ae2012-10-12 23:29:20 +0000967 if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
Michael Han51d8c522013-01-24 16:46:58 +0000968 RD->addAttr(::new (S.Context)
969 MsStructAttr(Attr.getRange(), S.Context,
970 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanianc1a0a732011-04-26 17:54:40 +0000971 else
972 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
973}
974
Chandler Carruth1b03c872011-07-02 00:01:44 +0000975static void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
Ted Kremenek96329d42008-07-15 22:26:48 +0000976 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +0000977 if (!checkAttributeNumArgs(S, Attr, 0))
Ted Kremenek96329d42008-07-15 22:26:48 +0000978 return;
Mike Stumpbf916502009-07-24 19:02:52 +0000979
Ted Kremenek63e5d7c2010-02-18 03:08:58 +0000980 // The IBAction attributes only apply to instance methods.
Chandler Carruth87c44602011-07-01 23:49:12 +0000981 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Ted Kremenek63e5d7c2010-02-18 03:08:58 +0000982 if (MD->isInstanceMethod()) {
Michael Han51d8c522013-01-24 16:46:58 +0000983 D->addAttr(::new (S.Context)
984 IBActionAttr(Attr.getRange(), S.Context,
985 Attr.getAttributeSpellingListIndex()));
Ted Kremenek63e5d7c2010-02-18 03:08:58 +0000986 return;
987 }
988
Ted Kremenek4ee2bb12011-02-04 06:54:16 +0000989 S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
Ted Kremenek63e5d7c2010-02-18 03:08:58 +0000990}
991
Ted Kremenek2f041d02011-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 Kremenek0bfaf062011-11-01 18:08:35 +0000998 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
Ted Kremenek2f041d02011-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 Gregorf6b8b582012-03-14 16:55:17 +00001005 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
Ted Kremenek2f041d02011-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 Gregorf6b8b582012-03-14 16:55:17 +00001014
Ted Kremenek2f041d02011-09-29 07:02:25 +00001015 return true;
1016}
1017
Chandler Carruth1b03c872011-07-02 00:01:44 +00001018static void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
Ted Kremenek63e5d7c2010-02-18 03:08:58 +00001019 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00001020 if (!checkAttributeNumArgs(S, Attr, 0))
Ted Kremenek63e5d7c2010-02-18 03:08:58 +00001021 return;
Ted Kremenek2f041d02011-09-29 07:02:25 +00001022
1023 if (!checkIBOutletCommon(S, D, Attr))
Ted Kremenek63e5d7c2010-02-18 03:08:58 +00001024 return;
Ted Kremenek63e5d7c2010-02-18 03:08:58 +00001025
Michael Han51d8c522013-01-24 16:46:58 +00001026 D->addAttr(::new (S.Context)
1027 IBOutletAttr(Attr.getRange(), S.Context,
1028 Attr.getAttributeSpellingListIndex()));
Ted Kremenek96329d42008-07-15 22:26:48 +00001029}
1030
Chandler Carruth1b03c872011-07-02 00:01:44 +00001031static void handleIBOutletCollection(Sema &S, Decl *D,
1032 const AttributeList &Attr) {
Ted Kremenek857e9182010-05-19 17:38:06 +00001033
1034 // The iboutletcollection attribute can have zero or one arguments.
Fariborz Jahaniana8fb24f2010-08-17 20:23:12 +00001035 if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
Ted Kremenek857e9182010-05-19 17:38:06 +00001036 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1037 return;
1038 }
1039
Ted Kremenek2f041d02011-09-29 07:02:25 +00001040 if (!checkIBOutletCommon(S, D, Attr))
Ted Kremenek857e9182010-05-19 17:38:06 +00001041 return;
Ted Kremenek2f041d02011-09-29 07:02:25 +00001042
Fariborz Jahaniana8fb24f2010-08-17 20:23:12 +00001043 IdentifierInfo *II = Attr.getParameterName();
1044 if (!II)
Fariborz Jahanianf4072ae2011-10-18 19:54:31 +00001045 II = &S.Context.Idents.get("NSObject");
Fariborz Jahanian3a3400b2010-08-17 21:39:27 +00001046
John McCallb3d87482010-08-24 05:47:05 +00001047 ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
Chandler Carruth87c44602011-07-01 23:49:12 +00001048 S.getScopeForContext(D->getDeclContext()->getParent()));
Fariborz Jahaniana8fb24f2010-08-17 20:23:12 +00001049 if (!TypeRep) {
1050 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
1051 return;
1052 }
John McCallb3d87482010-08-24 05:47:05 +00001053 QualType QT = TypeRep.get();
Fariborz Jahaniana8fb24f2010-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 Jahanianf4072ae2011-10-18 19:54:31 +00001058 if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
Fariborz Jahaniana8fb24f2010-08-17 20:23:12 +00001059 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
1060 return;
1061 }
Michael Han51d8c522013-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 Kremenek857e9182010-05-19 17:38:06 +00001066}
1067
Chandler Carruthd309c812011-07-01 23:49:16 +00001068static void possibleTransparentUnionPointerType(QualType &T) {
Fariborz Jahanian68fe96a2011-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 Lopes587de5b2012-05-24 00:22:00 +00001083static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Nuno Lopes174930d2012-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 Lopes587de5b2012-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 Lopes587de5b2012-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 Han51d8c522013-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 Lopes587de5b2012-05-24 00:22:00 +00001152}
1153
Chandler Carruth1b03c872011-07-02 00:01:44 +00001154static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Mike Stumpbf916502009-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 Carruth87c44602011-07-01 23:49:12 +00001157 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00001158 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001159 << Attr.getName() << ExpectedFunction;
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001160 return;
1161 }
Mike Stumpbf916502009-07-24 19:02:52 +00001162
Chandler Carruth07d7e7a2010-11-16 08:35:43 +00001163 // In C++ the implicit 'this' function parameter also counts, and they are
1164 // counted from one.
Chandler Carruth87c44602011-07-01 23:49:12 +00001165 bool HasImplicitThisParam = isInstanceMethod(D);
Nick Lewycky5d9484d2013-01-24 01:12:16 +00001166 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001167
1168 // The nonnull attribute only applies to pointers.
Chris Lattner5f9e2722011-07-23 10:55:15 +00001169 SmallVector<unsigned, 10> NonNullArgs;
Mike Stumpbf916502009-07-24 19:02:52 +00001170
Nick Lewycky5d9484d2013-01-24 01:12:16 +00001171 for (AttributeList::arg_iterator I = Attr.arg_begin(),
1172 E = Attr.arg_end(); I != E; ++I) {
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001173 // The argument must be an integer constant expression.
Peter Collingbourne7a730022010-11-23 20:45:58 +00001174 Expr *Ex = *I;
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001175 llvm::APSInt ArgNum(32);
Douglas Gregorac06a0e2010-05-18 23:01:22 +00001176 if (Ex->isTypeDependent() || Ex->isValueDependent() ||
1177 !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00001178 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1179 << "nonnull" << Ex->getSourceRange();
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001180 return;
1181 }
Mike Stumpbf916502009-07-24 19:02:52 +00001182
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001183 unsigned x = (unsigned) ArgNum.getZExtValue();
Mike Stumpbf916502009-07-24 19:02:52 +00001184
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001185 if (x < 1 || x > NumArgs) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00001186 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
Chris Lattner30bc9652008-11-19 07:22:31 +00001187 << "nonnull" << I.getArgNum() << Ex->getSourceRange();
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001188 return;
1189 }
Mike Stumpbf916502009-07-24 19:02:52 +00001190
Ted Kremenek465172f2008-07-21 22:09:15 +00001191 --x;
Chandler Carruth07d7e7a2010-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 Kremenekeb2b2a32008-07-21 21:53:04 +00001201
1202 // Is the function argument a pointer type?
Chandler Carruth87c44602011-07-01 23:49:12 +00001203 QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
Chandler Carruthd309c812011-07-01 23:49:16 +00001204 possibleTransparentUnionPointerType(T);
Fariborz Jahanian68fe96a2011-06-27 21:12:03 +00001205
Ted Kremenekdbfe99e2009-07-15 23:23:54 +00001206 if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001207 // FIXME: Should also highlight argument in decl.
Douglas Gregorc9ef4052010-08-12 18:48:43 +00001208 S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00001209 << "nonnull" << Ex->getSourceRange();
Ted Kremenek7fb43c12008-09-01 19:57:52 +00001210 continue;
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001211 }
Mike Stumpbf916502009-07-24 19:02:52 +00001212
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001213 NonNullArgs.push_back(x);
1214 }
Mike Stumpbf916502009-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 Kremenek7fb43c12008-09-01 19:57:52 +00001218 if (NonNullArgs.empty()) {
Nick Lewycky5d9484d2013-01-24 01:12:16 +00001219 for (unsigned i = 0, e = getFunctionOrMethodNumArgs(D); i != e; ++i) {
1220 QualType T = getFunctionOrMethodArgType(D, i).getNonReferenceType();
Chandler Carruthd309c812011-07-01 23:49:16 +00001221 possibleTransparentUnionPointerType(T);
Ted Kremenekdbfe99e2009-07-15 23:23:54 +00001222 if (T->isAnyPointerType() || T->isBlockPointerType())
Nick Lewycky5d9484d2013-01-24 01:12:16 +00001223 NonNullArgs.push_back(i);
Ted Kremenek46bbaca2008-11-18 06:52:58 +00001224 }
Mike Stumpbf916502009-07-24 19:02:52 +00001225
Ted Kremenekee1c08c2010-10-21 18:49:36 +00001226 // No pointer arguments?
Fariborz Jahanian60acea42010-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 Kremenek7fb43c12008-09-01 19:57:52 +00001232 return;
Fariborz Jahanian60acea42010-09-27 19:05:51 +00001233 }
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001234 }
Ted Kremenek7fb43c12008-09-01 19:57:52 +00001235
Nick Lewycky5d9484d2013-01-24 01:12:16 +00001236 unsigned *start = &NonNullArgs[0];
Ted Kremenek7fb43c12008-09-01 19:57:52 +00001237 unsigned size = NonNullArgs.size();
Ted Kremenekdd0e4902010-07-31 01:52:11 +00001238 llvm::array_pod_sort(start, start + size);
Michael Han51d8c522013-01-24 16:46:58 +00001239 D->addAttr(::new (S.Context)
1240 NonNullAttr(Attr.getRange(), S.Context, start, size,
1241 Attr.getAttributeSpellingListIndex()));
Ted Kremenekeb2b2a32008-07-21 21:53:04 +00001242}
1243
Chandler Carruth1b03c872011-07-02 00:01:44 +00001244static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
Ted Kremenekdd0e4902010-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 Rose2a479922010-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 Kremenekdd0e4902010-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.
Sean Huntcf807c42010-08-18 23:23:40 +00001260 OwnershipAttr::OwnershipKind K;
Jordy Rose2a479922010-08-12 08:54:03 +00001261 switch (AL.getKind()) {
1262 case AttributeList::AT_ownership_takes:
Sean Huntcf807c42010-08-18 23:23:40 +00001263 K = OwnershipAttr::Takes;
Ted Kremenekdd0e4902010-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 Rose2a479922010-08-12 08:54:03 +00001268 break;
1269 case AttributeList::AT_ownership_holds:
Sean Huntcf807c42010-08-18 23:23:40 +00001270 K = OwnershipAttr::Holds;
Ted Kremenekdd0e4902010-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 Rose2a479922010-08-12 08:54:03 +00001275 break;
1276 case AttributeList::AT_ownership_returns:
Sean Huntcf807c42010-08-18 23:23:40 +00001277 K = OwnershipAttr::Returns;
Ted Kremenekdd0e4902010-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 Rose2a479922010-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 Kremenekdd0e4902010-07-31 01:52:11 +00001287 }
1288
Chandler Carruth87c44602011-07-01 23:49:12 +00001289 if (!isFunction(D) || !hasFunctionProto(D)) {
John McCall883cc2c2011-03-02 12:29:23 +00001290 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
1291 << AL.getName() << ExpectedFunction;
Ted Kremenekdd0e4902010-07-31 01:52:11 +00001292 return;
1293 }
1294
Chandler Carruth07d7e7a2010-11-16 08:35:43 +00001295 // In C++ the implicit 'this' function parameter also counts, and they are
1296 // counted from one.
Chandler Carruth87c44602011-07-01 23:49:12 +00001297 bool HasImplicitThisParam = isInstanceMethod(D);
1298 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
Ted Kremenekdd0e4902010-07-31 01:52:11 +00001299
Chris Lattner5f9e2722011-07-23 10:55:15 +00001300 StringRef Module = AL.getParameterName()->getName();
Ted Kremenekdd0e4902010-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 Lattner5f9e2722011-07-23 10:55:15 +00001306 SmallVector<unsigned, 10> OwnershipArgs;
Ted Kremenekdd0e4902010-07-31 01:52:11 +00001307
Jordy Rose2a479922010-08-12 08:54:03 +00001308 for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
1309 ++I) {
Ted Kremenekdd0e4902010-07-31 01:52:11 +00001310
Peter Collingbourne7a730022010-11-23 20:45:58 +00001311 Expr *IdxExpr = *I;
Ted Kremenekdd0e4902010-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 Carruth07d7e7a2010-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 Kremenekdd0e4902010-07-31 01:52:11 +00001337 switch (K) {
Sean Huntcf807c42010-08-18 23:23:40 +00001338 case OwnershipAttr::Takes:
1339 case OwnershipAttr::Holds: {
Ted Kremenekdd0e4902010-07-31 01:52:11 +00001340 // Is the function argument a pointer type?
Chandler Carruth87c44602011-07-01 23:49:12 +00001341 QualType T = getFunctionOrMethodArgType(D, x);
Ted Kremenekdd0e4902010-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)
Sean Huntcf807c42010-08-18 23:23:40 +00001345 << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
Ted Kremenekdd0e4902010-07-31 01:52:11 +00001346 << "pointer"
1347 << IdxExpr->getSourceRange();
1348 continue;
1349 }
1350 break;
1351 }
Sean Huntcf807c42010-08-18 23:23:40 +00001352 case OwnershipAttr::Returns: {
Ted Kremenekdd0e4902010-07-31 01:52:11 +00001353 if (AL.getNumArgs() > 1) {
1354 // Is the function argument an integer type?
Peter Collingbourne7a730022010-11-23 20:45:58 +00001355 Expr *IdxExpr = AL.getArg(0);
Ted Kremenekdd0e4902010-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 Kremenekdd0e4902010-07-31 01:52:11 +00001367 } // switch
1368
1369 // Check we don't have a conflict with another ownership attribute.
Sean Huntcf807c42010-08-18 23:23:40 +00001370 for (specific_attr_iterator<OwnershipAttr>
Chandler Carruth87c44602011-07-01 23:49:12 +00001371 i = D->specific_attr_begin<OwnershipAttr>(),
1372 e = D->specific_attr_end<OwnershipAttr>();
Sean Huntcf807c42010-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 Kremenekdd0e4902010-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);
Sean Huntcf807c42010-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 Kremenekdd0e4902010-07-31 01:52:11 +00001394 }
Sean Huntcf807c42010-08-18 23:23:40 +00001395
Michael Han51d8c522013-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 Kremenekdd0e4902010-07-31 01:52:11 +00001399}
1400
Chandler Carruth1b03c872011-07-02 00:01:44 +00001401static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Rafael Espindola11e8ce72010-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 Carruth87c44602011-07-01 23:49:12 +00001408 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
John McCall332bb2a2011-02-08 22:35:49 +00001409 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001410 << Attr.getName() << ExpectedVariableOrFunction;
John McCall332bb2a2011-02-08 22:35:49 +00001411 return;
1412 }
1413
Chandler Carruth87c44602011-07-01 23:49:12 +00001414 NamedDecl *nd = cast<NamedDecl>(D);
John McCall332bb2a2011-02-08 22:35:49 +00001415
Rafael Espindola11e8ce72010-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 Carruth87c44602011-07-01 23:49:12 +00001426 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
Sebastian Redl7a126a42010-08-31 00:36:30 +00001427 if (!Ctx->isFileContext()) {
1428 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
John McCall332bb2a2011-02-08 22:35:49 +00001429 nd->getNameAsString();
Sebastian Redl7a126a42010-08-31 00:36:30 +00001430 return;
Rafael Espindola11e8ce72010-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 Espindola11e8ce72010-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 Collingbourne7a730022010-11-23 20:45:58 +00001456 Expr *Arg = Attr.getArg(0);
Rafael Espindola11e8ce72010-02-23 22:00:30 +00001457 Arg = Arg->IgnoreParenCasts();
1458 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1459
Douglas Gregor5cee1192011-07-27 05:40:30 +00001460 if (!Str || !Str->isAscii()) {
Rafael Espindola11e8ce72010-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 Kyrtzidis768d6ca2011-09-13 16:05:58 +00001467 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
Eric Christopherf48f3672010-12-01 22:13:54 +00001468 Str->getString()));
Rafael Espindola11e8ce72010-02-23 22:00:30 +00001469 }
1470
Michael Han51d8c522013-01-24 16:46:58 +00001471 D->addAttr(::new (S.Context)
1472 WeakRefAttr(Attr.getRange(), S.Context,
1473 Attr.getAttributeSpellingListIndex()));
Rafael Espindola11e8ce72010-02-23 22:00:30 +00001474}
1475
Chandler Carruth1b03c872011-07-02 00:01:44 +00001476static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner6b6b5372008-06-26 18:38:35 +00001477 // check the attribute arguments.
Chris Lattner545dd342008-06-28 23:36:30 +00001478 if (Attr.getNumArgs() != 1) {
Chris Lattner3c73c412008-11-19 08:23:25 +00001479 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
Chris Lattner6b6b5372008-06-26 18:38:35 +00001480 return;
1481 }
Mike Stumpbf916502009-07-24 19:02:52 +00001482
Peter Collingbourne7a730022010-11-23 20:45:58 +00001483 Expr *Arg = Attr.getArg(0);
Chris Lattner6b6b5372008-06-26 18:38:35 +00001484 Arg = Arg->IgnoreParenCasts();
1485 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
Mike Stumpbf916502009-07-24 19:02:52 +00001486
Douglas Gregor5cee1192011-07-27 05:40:30 +00001487 if (!Str || !Str->isAscii()) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00001488 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
Chris Lattner3c73c412008-11-19 08:23:25 +00001489 << "alias" << 1;
Chris Lattner6b6b5372008-06-26 18:38:35 +00001490 return;
1491 }
Mike Stumpbf916502009-07-24 19:02:52 +00001492
Douglas Gregorbcfd1f52011-09-02 00:18:52 +00001493 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
Rafael Espindolaf5fe2922010-12-07 15:23:23 +00001494 S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1495 return;
1496 }
1497
Chris Lattner6b6b5372008-06-26 18:38:35 +00001498 // FIXME: check if target symbol exists in current file
Mike Stumpbf916502009-07-24 19:02:52 +00001499
Argyrios Kyrtzidis768d6ca2011-09-13 16:05:58 +00001500 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
Michael Han51d8c522013-01-24 16:46:58 +00001501 Str->getString(),
1502 Attr.getAttributeSpellingListIndex()));
Chris Lattner6b6b5372008-06-26 18:38:35 +00001503}
1504
Quentin Colombetaee56fa2012-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 Han51d8c522013-01-24 16:46:58 +00001516 D->addAttr(::new (S.Context)
1517 MinSizeAttr(Attr.getRange(), S.Context,
1518 Attr.getAttributeSpellingListIndex()));
Quentin Colombetaee56fa2012-11-01 23:55:47 +00001519}
1520
Benjamin Krameree409a92012-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 Han51d8c522013-01-24 16:46:58 +00001538 D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context,
1539 Attr.getAttributeSpellingListIndex()));
Benjamin Krameree409a92012-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 Han51d8c522013-01-24 16:46:58 +00001559 D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context,
1560 Attr.getAttributeSpellingListIndex()));
Benjamin Krameree409a92012-05-12 21:10:52 +00001561}
1562
Chandler Carruth1b03c872011-07-02 00:01:44 +00001563static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbardd0cb222010-09-29 18:20:25 +00001564 // Check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00001565 if (!checkAttributeNumArgs(S, Attr, 0))
Daniel Dunbaraf668b02008-10-28 00:17:57 +00001566 return;
Anders Carlsson5bab7882009-02-19 19:16:48 +00001567
Chandler Carruth87c44602011-07-01 23:49:12 +00001568 if (!isa<FunctionDecl>(D)) {
Anders Carlsson5bab7882009-02-19 19:16:48 +00001569 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001570 << Attr.getName() << ExpectedFunction;
Daniel Dunbardd0cb222010-09-29 18:20:25 +00001571 return;
1572 }
1573
Michael Han51d8c522013-01-24 16:46:58 +00001574 D->addAttr(::new (S.Context)
1575 NakedAttr(Attr.getRange(), S.Context,
1576 Attr.getAttributeSpellingListIndex()));
Daniel Dunbardd0cb222010-09-29 18:20:25 +00001577}
1578
Chandler Carruth1b03c872011-07-02 00:01:44 +00001579static void handleAlwaysInlineAttr(Sema &S, Decl *D,
1580 const AttributeList &Attr) {
Daniel Dunbardd0cb222010-09-29 18:20:25 +00001581 // Check the attribute arguments.
Ted Kremenek831efae2011-04-15 05:49:29 +00001582 if (Attr.hasParameterOrArguments()) {
Daniel Dunbardd0cb222010-09-29 18:20:25 +00001583 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1584 return;
1585 }
1586
Chandler Carruth87c44602011-07-01 23:49:12 +00001587 if (!isa<FunctionDecl>(D)) {
Daniel Dunbardd0cb222010-09-29 18:20:25 +00001588 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001589 << Attr.getName() << ExpectedFunction;
Anders Carlsson5bab7882009-02-19 19:16:48 +00001590 return;
1591 }
Mike Stumpbf916502009-07-24 19:02:52 +00001592
Michael Han51d8c522013-01-24 16:46:58 +00001593 D->addAttr(::new (S.Context)
1594 AlwaysInlineAttr(Attr.getRange(), S.Context,
1595 Attr.getAttributeSpellingListIndex()));
Daniel Dunbaraf668b02008-10-28 00:17:57 +00001596}
1597
Hans Wennborg5e2d5de2012-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 Han51d8c522013-01-24 16:46:58 +00001630 D->addAttr(::new (S.Context)
1631 TLSModelAttr(Attr.getRange(), S.Context, Model,
1632 Attr.getAttributeSpellingListIndex()));
Hans Wennborg5e2d5de2012-06-23 11:51:46 +00001633}
1634
Chandler Carruth1b03c872011-07-02 00:01:44 +00001635static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbardd0cb222010-09-29 18:20:25 +00001636 // Check the attribute arguments.
Ted Kremenek831efae2011-04-15 05:49:29 +00001637 if (Attr.hasParameterOrArguments()) {
Ryan Flynn76168e22009-08-09 20:07:29 +00001638 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1639 return;
1640 }
Mike Stump1eb44332009-09-09 15:08:12 +00001641
Chandler Carruth87c44602011-07-01 23:49:12 +00001642 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
Mike Stump1eb44332009-09-09 15:08:12 +00001643 QualType RetTy = FD->getResultType();
Ted Kremenek2cff7d12009-08-15 00:51:46 +00001644 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
Michael Han51d8c522013-01-24 16:46:58 +00001645 D->addAttr(::new (S.Context)
1646 MallocAttr(Attr.getRange(), S.Context,
1647 Attr.getAttributeSpellingListIndex()));
Ted Kremenek2cff7d12009-08-15 00:51:46 +00001648 return;
1649 }
Ryan Flynn76168e22009-08-09 20:07:29 +00001650 }
1651
Ted Kremenek2cff7d12009-08-15 00:51:46 +00001652 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
Ryan Flynn76168e22009-08-09 20:07:29 +00001653}
1654
Chandler Carruth1b03c872011-07-02 00:01:44 +00001655static void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Dan Gohman34c26302010-11-17 00:03:07 +00001656 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00001657 if (!checkAttributeNumArgs(S, Attr, 0))
Dan Gohman34c26302010-11-17 00:03:07 +00001658 return;
Dan Gohman34c26302010-11-17 00:03:07 +00001659
Michael Han51d8c522013-01-24 16:46:58 +00001660 D->addAttr(::new (S.Context)
1661 MayAliasAttr(Attr.getRange(), S.Context,
1662 Attr.getAttributeSpellingListIndex()));
Dan Gohman34c26302010-11-17 00:03:07 +00001663}
1664
Chandler Carruth1b03c872011-07-02 00:01:44 +00001665static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruth56aeb402011-07-11 23:33:05 +00001666 assert(!Attr.isInvalid());
Chandler Carruth87c44602011-07-01 23:49:12 +00001667 if (isa<VarDecl>(D))
Michael Han51d8c522013-01-24 16:46:58 +00001668 D->addAttr(::new (S.Context)
1669 NoCommonAttr(Attr.getRange(), S.Context,
1670 Attr.getAttributeSpellingListIndex()));
Eric Christopher722109c2010-12-03 06:58:14 +00001671 else
1672 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001673 << Attr.getName() << ExpectedVariable;
Eric Christophera6cf1e72010-12-02 02:45:55 +00001674}
1675
Chandler Carruth1b03c872011-07-02 00:01:44 +00001676static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruth56aeb402011-07-11 23:33:05 +00001677 assert(!Attr.isInvalid());
Chandler Carruth87c44602011-07-01 23:49:12 +00001678 if (isa<VarDecl>(D))
Michael Han51d8c522013-01-24 16:46:58 +00001679 D->addAttr(::new (S.Context)
1680 CommonAttr(Attr.getRange(), S.Context,
1681 Attr.getAttributeSpellingListIndex()));
Eric Christopher722109c2010-12-03 06:58:14 +00001682 else
1683 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001684 << Attr.getName() << ExpectedVariable;
Eric Christophera6cf1e72010-12-02 02:45:55 +00001685}
1686
Chandler Carruth1b03c872011-07-02 00:01:44 +00001687static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
Chandler Carruth87c44602011-07-01 23:49:12 +00001688 if (hasDeclarator(D)) return;
John McCall711c52b2011-01-05 12:14:39 +00001689
1690 if (S.CheckNoReturnAttr(attr)) return;
1691
Chandler Carruth87c44602011-07-01 23:49:12 +00001692 if (!isa<ObjCMethodDecl>(D)) {
John McCall711c52b2011-01-05 12:14:39 +00001693 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001694 << attr.getName() << ExpectedFunctionOrMethod;
John McCall711c52b2011-01-05 12:14:39 +00001695 return;
1696 }
1697
Michael Han51d8c522013-01-24 16:46:58 +00001698 D->addAttr(::new (S.Context)
1699 NoReturnAttr(attr.getRange(), S.Context,
1700 attr.getAttributeSpellingListIndex()));
John McCall711c52b2011-01-05 12:14:39 +00001701}
1702
1703bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
Ted Kremenek831efae2011-04-15 05:49:29 +00001704 if (attr.hasParameterOrArguments()) {
John McCall711c52b2011-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 Kremenekb7252322009-04-10 00:01:14 +00001711}
1712
Chandler Carruth1b03c872011-07-02 00:01:44 +00001713static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
1714 const AttributeList &Attr) {
Ted Kremenekb56c1cc2010-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 Carruth1731e202011-07-11 23:30:35 +00001719 if(!checkAttributeNumArgs(S, Attr, 0))
1720 return;
Ted Kremenekb56c1cc2010-08-19 00:51:58 +00001721
Chandler Carruth87c44602011-07-01 23:49:12 +00001722 if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
1723 ValueDecl *VD = dyn_cast<ValueDecl>(D);
Ted Kremenekb56c1cc2010-08-19 00:51:58 +00001724 if (VD == 0 || (!VD->getType()->isBlockPointerType()
1725 && !VD->getType()->isFunctionPointerType())) {
1726 S.Diag(Attr.getLoc(),
Richard Smith4e24f0f2013-01-02 12:01:23 +00001727 Attr.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type
Ted Kremenekb56c1cc2010-08-19 00:51:58 +00001728 : diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001729 << Attr.getName() << ExpectedFunctionMethodOrBlock;
Ted Kremenekb56c1cc2010-08-19 00:51:58 +00001730 return;
1731 }
1732 }
1733
Michael Han51d8c522013-01-24 16:46:58 +00001734 D->addAttr(::new (S.Context)
1735 AnalyzerNoReturnAttr(Attr.getRange(), S.Context,
1736 Attr.getAttributeSpellingListIndex()));
Chris Lattner6b6b5372008-06-26 18:38:35 +00001737}
1738
Richard Smithcd8ab512013-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 Han51d8c522013-01-24 16:46:58 +00001751 D->addAttr(::new (S.Context)
1752 CXX11NoReturnAttr(Attr.getRange(), S.Context,
1753 Attr.getAttributeSpellingListIndex()));
Richard Smithcd8ab512013-01-17 01:30:42 +00001754}
1755
John Thompson35cc9622010-08-09 21:53:52 +00001756// PS3 PPU-specific.
Chandler Carruth1b03c872011-07-02 00:01:44 +00001757static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
John Thompson35cc9622010-08-09 21:53:52 +00001758/*
1759 Returning a Vector Class in Registers
1760
Eric Christopherf48f3672010-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 Thompson35cc9622010-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 Carruth87c44602011-07-01 23:49:12 +00001781 if (!isa<RecordDecl>(D)) {
John Thompson35cc9622010-08-09 21:53:52 +00001782 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001783 << Attr.getName() << ExpectedClass;
John Thompson35cc9622010-08-09 21:53:52 +00001784 return;
1785 }
1786
Chandler Carruth87c44602011-07-01 23:49:12 +00001787 if (D->getAttr<VecReturnAttr>()) {
John Thompson35cc9622010-08-09 21:53:52 +00001788 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
1789 return;
1790 }
1791
Chandler Carruth87c44602011-07-01 23:49:12 +00001792 RecordDecl *record = cast<RecordDecl>(D);
John Thompson01add592010-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 Christopherf48f3672010-12-01 22:13:54 +00001805 for (RecordDecl::field_iterator iter = record->field_begin();
1806 iter != record->field_end(); iter++) {
John Thompson01add592010-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 Han51d8c522013-01-24 16:46:58 +00001814 D->addAttr(::new (S.Context)
1815 VecReturnAttr(Attr.getRange(), S.Context,
1816 Attr.getAttributeSpellingListIndex()));
John Thompson35cc9622010-08-09 21:53:52 +00001817}
1818
Richard Smith3a2b7a12013-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)) {
Sean Huntbbd37c62009-11-21 08:43:09 +00001830 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001831 << Attr.getName() << ExpectedFunctionMethodOrParameter;
Sean Huntbbd37c62009-11-21 08:43:09 +00001832 return;
1833 }
Richard Smith3a2b7a12013-01-28 22:42:45 +00001834
1835 D->addAttr(::new (S.Context) CarriesDependencyAttr(
1836 Attr.getRange(), S.Context,
1837 Attr.getAttributeSpellingListIndex()));
Sean Huntbbd37c62009-11-21 08:43:09 +00001838}
1839
Chandler Carruth1b03c872011-07-02 00:01:44 +00001840static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Ted Kremenek73798892008-07-25 04:39:19 +00001841 // check the attribute arguments.
Ted Kremenek831efae2011-04-15 05:49:29 +00001842 if (Attr.hasParameterOrArguments()) {
Chris Lattner3c73c412008-11-19 08:23:25 +00001843 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
Ted Kremenek73798892008-07-25 04:39:19 +00001844 return;
1845 }
Mike Stumpbf916502009-07-24 19:02:52 +00001846
Chandler Carruth87c44602011-07-01 23:49:12 +00001847 if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
Daniel Jasper568eae42012-06-13 18:31:09 +00001848 !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00001849 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001850 << Attr.getName() << ExpectedVariableFunctionOrLabel;
Ted Kremenek73798892008-07-25 04:39:19 +00001851 return;
1852 }
Mike Stumpbf916502009-07-24 19:02:52 +00001853
Michael Han51d8c522013-01-24 16:46:58 +00001854 D->addAttr(::new (S.Context)
1855 UnusedAttr(Attr.getRange(), S.Context,
1856 Attr.getAttributeSpellingListIndex()));
Ted Kremenek73798892008-07-25 04:39:19 +00001857}
1858
Rafael Espindolaf87cced2011-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 Han51d8c522013-01-24 16:46:58 +00001873 D->addAttr(::new (S.Context)
1874 ReturnsTwiceAttr(Attr.getRange(), S.Context,
1875 Attr.getAttributeSpellingListIndex()));
Rafael Espindolaf87cced2011-10-03 14:59:42 +00001876}
1877
Chandler Carruth1b03c872011-07-02 00:01:44 +00001878static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbarb805dad2009-02-13 19:23:53 +00001879 // check the attribute arguments.
Ted Kremenek831efae2011-04-15 05:49:29 +00001880 if (Attr.hasParameterOrArguments()) {
Daniel Dunbarb805dad2009-02-13 19:23:53 +00001881 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1882 return;
1883 }
Mike Stumpbf916502009-07-24 19:02:52 +00001884
Chandler Carruth87c44602011-07-01 23:49:12 +00001885 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Daniel Dunbar186204b2009-02-13 22:48:56 +00001886 if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
Daniel Dunbarb805dad2009-02-13 19:23:53 +00001887 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
1888 return;
1889 }
Chandler Carruth87c44602011-07-01 23:49:12 +00001890 } else if (!isFunctionOrMethod(D)) {
Daniel Dunbarb805dad2009-02-13 19:23:53 +00001891 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001892 << Attr.getName() << ExpectedVariableOrFunction;
Daniel Dunbarb805dad2009-02-13 19:23:53 +00001893 return;
1894 }
Mike Stumpbf916502009-07-24 19:02:52 +00001895
Michael Han51d8c522013-01-24 16:46:58 +00001896 D->addAttr(::new (S.Context)
1897 UsedAttr(Attr.getRange(), S.Context,
1898 Attr.getAttributeSpellingListIndex()));
Daniel Dunbarb805dad2009-02-13 19:23:53 +00001899}
1900
Chandler Carruth1b03c872011-07-02 00:01:44 +00001901static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001902 // check the attribute arguments.
John McCallbdc49d32011-03-02 12:15:05 +00001903 if (Attr.getNumArgs() > 1) {
1904 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001905 return;
Mike Stumpbf916502009-07-24 19:02:52 +00001906 }
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001907
1908 int priority = 65535; // FIXME: Do not hardcode such constants.
1909 if (Attr.getNumArgs() > 0) {
Peter Collingbourne7a730022010-11-23 20:45:58 +00001910 Expr *E = Attr.getArg(0);
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001911 llvm::APSInt Idx(32);
Douglas Gregorac06a0e2010-05-18 23:01:22 +00001912 if (E->isTypeDependent() || E->isValueDependent() ||
1913 !E->isIntegerConstantExpr(Idx, S.Context)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00001914 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner3c73c412008-11-19 08:23:25 +00001915 << "constructor" << 1 << E->getSourceRange();
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001916 return;
1917 }
1918 priority = Idx.getZExtValue();
1919 }
Mike Stumpbf916502009-07-24 19:02:52 +00001920
Chandler Carruth87c44602011-07-01 23:49:12 +00001921 if (!isa<FunctionDecl>(D)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00001922 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001923 << Attr.getName() << ExpectedFunction;
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001924 return;
1925 }
1926
Michael Han51d8c522013-01-24 16:46:58 +00001927 D->addAttr(::new (S.Context)
1928 ConstructorAttr(Attr.getRange(), S.Context, priority,
1929 Attr.getAttributeSpellingListIndex()));
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001930}
1931
Chandler Carruth1b03c872011-07-02 00:01:44 +00001932static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001933 // check the attribute arguments.
John McCallbdc49d32011-03-02 12:15:05 +00001934 if (Attr.getNumArgs() > 1) {
1935 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001936 return;
Mike Stumpbf916502009-07-24 19:02:52 +00001937 }
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001938
1939 int priority = 65535; // FIXME: Do not hardcode such constants.
1940 if (Attr.getNumArgs() > 0) {
Peter Collingbourne7a730022010-11-23 20:45:58 +00001941 Expr *E = Attr.getArg(0);
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001942 llvm::APSInt Idx(32);
Douglas Gregorac06a0e2010-05-18 23:01:22 +00001943 if (E->isTypeDependent() || E->isValueDependent() ||
1944 !E->isIntegerConstantExpr(Idx, S.Context)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00001945 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner3c73c412008-11-19 08:23:25 +00001946 << "destructor" << 1 << E->getSourceRange();
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001947 return;
1948 }
1949 priority = Idx.getZExtValue();
1950 }
Mike Stumpbf916502009-07-24 19:02:52 +00001951
Chandler Carruth87c44602011-07-01 23:49:12 +00001952 if (!isa<FunctionDecl>(D)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00001953 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00001954 << Attr.getName() << ExpectedFunction;
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001955 return;
1956 }
1957
Michael Han51d8c522013-01-24 16:46:58 +00001958 D->addAttr(::new (S.Context)
1959 DestructorAttr(Attr.getRange(), S.Context, priority,
1960 Attr.getAttributeSpellingListIndex()));
Daniel Dunbar3068ae02008-07-31 22:40:48 +00001961}
1962
Benjamin Kramerbc3260d2012-05-16 12:19:08 +00001963template <typename AttrTy>
1964static void handleAttrWithMessage(Sema &S, Decl *D, const AttributeList &Attr,
1965 const char *Name) {
Chris Lattner951bbb22011-02-24 05:42:24 +00001966 unsigned NumArgs = Attr.getNumArgs();
1967 if (NumArgs > 1) {
John McCallbdc49d32011-03-02 12:15:05 +00001968 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
Chris Lattner6b6b5372008-06-26 18:38:35 +00001969 return;
1970 }
Benjamin Kramerbc3260d2012-05-16 12:19:08 +00001971
1972 // Handle the case where the attribute has a text message.
Chris Lattner5f9e2722011-07-23 10:55:15 +00001973 StringRef Str;
Chris Lattner951bbb22011-02-24 05:42:24 +00001974 if (NumArgs == 1) {
1975 StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
Fariborz Jahanianc4b35cf2010-10-06 21:18:44 +00001976 if (!SE) {
Chris Lattner951bbb22011-02-24 05:42:24 +00001977 S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
Benjamin Kramerbc3260d2012-05-16 12:19:08 +00001978 << Name;
Fariborz Jahanianc4b35cf2010-10-06 21:18:44 +00001979 return;
1980 }
Chris Lattner951bbb22011-02-24 05:42:24 +00001981 Str = SE->getString();
Fariborz Jahanianc4b35cf2010-10-06 21:18:44 +00001982 }
Mike Stumpbf916502009-07-24 19:02:52 +00001983
Michael Han51d8c522013-01-24 16:46:58 +00001984 D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str,
1985 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanianbc1c8772008-12-17 01:07:27 +00001986}
1987
Fariborz Jahanian742352a2011-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 Han51d8c522013-01-24 16:46:58 +00001996 D->addAttr(::new (S.Context)
1997 ArcWeakrefUnavailableAttr(Attr.getRange(), S.Context,
1998 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanian742352a2011-07-06 19:24:05 +00001999}
2000
Patrick Beardb2f68202012-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 Han51d8c522013-01-24 16:46:58 +00002014 D->addAttr(::new (S.Context)
2015 ObjCRootClassAttr(Attr.getRange(), S.Context,
2016 Attr.getAttributeSpellingListIndex()));
Patrick Beardb2f68202012-04-06 18:12:22 +00002017}
2018
Michael Han51d8c522013-01-24 16:46:58 +00002019static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
2020 const AttributeList &Attr) {
Fariborz Jahanian341b8be2012-01-03 22:52:32 +00002021 if (!isa<ObjCInterfaceDecl>(D)) {
2022 S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
2023 return;
2024 }
2025
Fariborz Jahaniane23dcf32012-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 Han51d8c522013-01-24 16:46:58 +00002032 D->addAttr(::new (S.Context)
2033 ObjCRequiresPropertyDefsAttr(Attr.getRange(), S.Context,
2034 Attr.getAttributeSpellingListIndex()));
Fariborz Jahaniane23dcf32012-01-03 18:45:41 +00002035}
2036
Jordy Rosefad5de92012-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 Espindola3b294362012-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 Gregorf4d918f2013-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 Espindola51be6e32013-01-08 22:04:34 +00002094AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
Rafael Espindola599f1b72012-05-13 03:25:18 +00002095 IdentifierInfo *Platform,
2096 VersionTuple Introduced,
2097 VersionTuple Deprecated,
2098 VersionTuple Obsoleted,
2099 bool IsUnavailable,
Douglas Gregorf4d918f2013-01-15 22:43:08 +00002100 StringRef Message,
Michael Han51d8c522013-01-24 16:46:58 +00002101 bool Override,
2102 unsigned AttrSpellingListIndex) {
Rafael Espindola98ae8342012-05-10 02:50:16 +00002103 VersionTuple MergedIntroduced = Introduced;
2104 VersionTuple MergedDeprecated = Deprecated;
2105 VersionTuple MergedObsoleted = Obsoleted;
Rafael Espindola3b294362012-05-06 19:56:25 +00002106 bool FoundAny = false;
2107
Rafael Espindola98ae8342012-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 Espindola3b294362012-05-06 19:56:25 +00002116
Rafael Espindola98ae8342012-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 Espindola98ae8342012-05-10 02:50:16 +00002128
Douglas Gregorf4d918f2013-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 Gregor72daa3f2013-01-16 00:54:48 +00002133 (Override && !OldIsUnavailable && IsUnavailable))) {
Douglas Gregorf4d918f2013-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 Espindola98ae8342012-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 Espindola3b294362012-05-06 19:56:25 +00002197 }
Rafael Espindola3b294362012-05-06 19:56:25 +00002198 }
2199
2200 if (FoundAny &&
2201 MergedIntroduced == Introduced &&
2202 MergedDeprecated == Deprecated &&
2203 MergedObsoleted == Obsoleted)
Rafael Espindola599f1b72012-05-13 03:25:18 +00002204 return NULL;
Rafael Espindola3b294362012-05-06 19:56:25 +00002205
Rafael Espindola98ae8342012-05-10 02:50:16 +00002206 if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
Rafael Espindola3b294362012-05-06 19:56:25 +00002207 MergedDeprecated, MergedObsoleted)) {
Rafael Espindola599f1b72012-05-13 03:25:18 +00002208 return ::new (Context) AvailabilityAttr(Range, Context, Platform,
2209 Introduced, Deprecated,
Michael Han51d8c522013-01-24 16:46:58 +00002210 Obsoleted, IsUnavailable, Message,
2211 AttrSpellingListIndex);
Rafael Espindola3b294362012-05-06 19:56:25 +00002212 }
Rafael Espindola599f1b72012-05-13 03:25:18 +00002213 return NULL;
Rafael Espindola3b294362012-05-06 19:56:25 +00002214}
2215
Chandler Carruth1b03c872011-07-02 00:01:44 +00002216static void handleAvailabilityAttr(Sema &S, Decl *D,
2217 const AttributeList &Attr) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00002218 IdentifierInfo *Platform = Attr.getParameterName();
2219 SourceLocation PlatformLoc = Attr.getParameterLoc();
Michael Han51d8c522013-01-24 16:46:58 +00002220 unsigned Index = Attr.getAttributeSpellingListIndex();
2221
Rafael Espindola3b294362012-05-06 19:56:25 +00002222 if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty())
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00002223 S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
2224 << Platform;
2225
Rafael Espindola8c4222a2013-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 Gregor0a0d2b12011-03-23 00:50:03 +00002232 AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
2233 AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
2234 AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
Douglas Gregorb53e4172011-03-26 03:35:55 +00002235 bool IsUnavailable = Attr.getUnavailableLoc().isValid();
Fariborz Jahanian006e42f2011-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 Espindola3b294362012-05-06 19:56:25 +00002241
Rafael Espindola51be6e32013-01-08 22:04:34 +00002242 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(),
Rafael Espindola599f1b72012-05-13 03:25:18 +00002243 Platform,
2244 Introduced.Version,
2245 Deprecated.Version,
2246 Obsoleted.Version,
Douglas Gregorf4d918f2013-01-15 22:43:08 +00002247 IsUnavailable, Str,
Michael Han51d8c522013-01-24 16:46:58 +00002248 /*Override=*/false,
2249 Index);
Rafael Espindola838dc592013-01-12 06:42:30 +00002250 if (NewAttr)
Rafael Espindola599f1b72012-05-13 03:25:18 +00002251 D->addAttr(NewAttr);
Rafael Espindola98ae8342012-05-10 02:50:16 +00002252}
2253
Rafael Espindola599f1b72012-05-13 03:25:18 +00002254VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
Michael Han51d8c522013-01-24 16:46:58 +00002255 VisibilityAttr::VisibilityType Vis,
2256 unsigned AttrSpellingListIndex) {
Rafael Espindoladd44f342012-05-10 03:01:34 +00002257 if (isa<TypedefNameDecl>(D)) {
2258 Diag(Range.getBegin(), diag::warn_attribute_ignored) << "visibility";
Rafael Espindola599f1b72012-05-13 03:25:18 +00002259 return NULL;
Rafael Espindoladd44f342012-05-10 03:01:34 +00002260 }
Rafael Espindola98ae8342012-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 Espindola599f1b72012-05-13 03:25:18 +00002265 return NULL;
Rafael Espindola98ae8342012-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 Han51d8c522013-01-24 16:46:58 +00002270 return ::new (Context) VisibilityAttr(Range, Context, Vis,
2271 AttrSpellingListIndex);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00002272}
2273
Chandler Carruth1b03c872011-07-02 00:01:44 +00002274static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner6b6b5372008-06-26 18:38:35 +00002275 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00002276 if(!checkAttributeNumArgs(S, Attr, 1))
Chris Lattner6b6b5372008-06-26 18:38:35 +00002277 return;
Mike Stumpbf916502009-07-24 19:02:52 +00002278
Peter Collingbourne7a730022010-11-23 20:45:58 +00002279 Expr *Arg = Attr.getArg(0);
Chris Lattner6b6b5372008-06-26 18:38:35 +00002280 Arg = Arg->IgnoreParenCasts();
2281 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
Mike Stumpbf916502009-07-24 19:02:52 +00002282
Douglas Gregor5cee1192011-07-27 05:40:30 +00002283 if (!Str || !Str->isAscii()) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00002284 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
Chris Lattner3c73c412008-11-19 08:23:25 +00002285 << "visibility" << 1;
Chris Lattner6b6b5372008-06-26 18:38:35 +00002286 return;
2287 }
Mike Stumpbf916502009-07-24 19:02:52 +00002288
Chris Lattner5f9e2722011-07-23 10:55:15 +00002289 StringRef TypeStr = Str->getString();
Sean Huntcf807c42010-08-18 23:23:40 +00002290 VisibilityAttr::VisibilityType type;
Michael Han51d8c522013-01-24 16:46:58 +00002291
Benjamin Kramerc96f4942010-01-23 18:16:35 +00002292 if (TypeStr == "default")
Sean Huntcf807c42010-08-18 23:23:40 +00002293 type = VisibilityAttr::Default;
Benjamin Kramerc96f4942010-01-23 18:16:35 +00002294 else if (TypeStr == "hidden")
Sean Huntcf807c42010-08-18 23:23:40 +00002295 type = VisibilityAttr::Hidden;
Benjamin Kramerc96f4942010-01-23 18:16:35 +00002296 else if (TypeStr == "internal")
Sean Huntcf807c42010-08-18 23:23:40 +00002297 type = VisibilityAttr::Hidden; // FIXME
John McCall41887602012-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 Lattner08631c52008-11-23 21:45:46 +00002308 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
Chris Lattner6b6b5372008-06-26 18:38:35 +00002309 return;
2310 }
Mike Stumpbf916502009-07-24 19:02:52 +00002311
Michael Han51d8c522013-01-24 16:46:58 +00002312 unsigned Index = Attr.getAttributeSpellingListIndex();
2313 VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type,
2314 Index);
Rafael Espindola838dc592013-01-12 06:42:30 +00002315 if (NewAttr)
Rafael Espindola599f1b72012-05-13 03:25:18 +00002316 D->addAttr(NewAttr);
Chris Lattner6b6b5372008-06-26 18:38:35 +00002317}
2318
Chandler Carruth1b03c872011-07-02 00:01:44 +00002319static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
2320 const AttributeList &Attr) {
John McCalld5313b02011-03-02 11:33:24 +00002321 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
2322 if (!method) {
Chandler Carruth87c44602011-07-01 23:49:12 +00002323 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00002324 << ExpectedMethod;
John McCalld5313b02011-03-02 11:33:24 +00002325 return;
2326 }
2327
Chandler Carruth87c44602011-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 McCalld5313b02011-03-02 11:33:24 +00002331 << "objc_method_family" << 1;
2332 } else {
Chandler Carruth87c44602011-07-01 23:49:12 +00002333 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
John McCalld5313b02011-03-02 11:33:24 +00002334 }
Chandler Carruth87c44602011-07-01 23:49:12 +00002335 Attr.setInvalid();
John McCalld5313b02011-03-02 11:33:24 +00002336 return;
2337 }
2338
Chris Lattner5f9e2722011-07-23 10:55:15 +00002339 StringRef param = Attr.getParameterName()->getName();
John McCalld5313b02011-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 Carruth87c44602011-07-01 23:49:12 +00002356 S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
John McCalld5313b02011-03-02 11:33:24 +00002357 return;
2358 }
2359
John McCallf85e1932011-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 Kyrtzidis768d6ca2011-09-13 16:05:58 +00002368 method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
John McCallf85e1932011-06-15 23:02:42 +00002369 S.Context, family));
John McCalld5313b02011-03-02 11:33:24 +00002370}
2371
Chandler Carruth1b03c872011-07-02 00:01:44 +00002372static void handleObjCExceptionAttr(Sema &S, Decl *D,
2373 const AttributeList &Attr) {
Chandler Carruth1731e202011-07-11 23:30:35 +00002374 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattner0db29ec2009-02-14 08:09:34 +00002375 return;
Mike Stumpbf916502009-07-24 19:02:52 +00002376
Chris Lattner0db29ec2009-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 Stumpbf916502009-07-24 19:02:52 +00002382
Michael Han51d8c522013-01-24 16:46:58 +00002383 D->addAttr(::new (S.Context)
2384 ObjCExceptionAttr(Attr.getRange(), S.Context,
2385 Attr.getAttributeSpellingListIndex()));
Chris Lattner0db29ec2009-02-14 08:09:34 +00002386}
2387
Chandler Carruth1b03c872011-07-02 00:01:44 +00002388static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
Fariborz Jahanianfa23c1d2009-01-13 23:34:40 +00002389 if (Attr.getNumArgs() != 0) {
John McCall2b7baf02010-05-28 18:25:28 +00002390 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
Fariborz Jahanianfa23c1d2009-01-13 23:34:40 +00002391 return;
2392 }
Richard Smith162e1c12011-04-15 14:24:37 +00002393 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
Fariborz Jahanianfa23c1d2009-01-13 23:34:40 +00002394 QualType T = TD->getUnderlyingType();
Ted Kremenek9af91222012-08-29 22:54:47 +00002395 if (!T->isCARCBridgableType()) {
Fariborz Jahanianfa23c1d2009-01-13 23:34:40 +00002396 S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
2397 return;
2398 }
2399 }
Fariborz Jahanian34276822012-05-31 23:18:32 +00002400 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
2401 QualType T = PD->getType();
Ted Kremenek9af91222012-08-29 22:54:47 +00002402 if (!T->isCARCBridgableType()) {
Fariborz Jahanian34276822012-05-31 23:18:32 +00002403 S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
2404 return;
2405 }
2406 }
2407 else {
Ted Kremenekf6e88d72012-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 Jahanian9b2eb7b2011-11-29 01:48:40 +00002414 S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
Ted Kremenekf6e88d72012-03-01 01:40:32 +00002415 }
Michael Han51d8c522013-01-24 16:46:58 +00002416 D->addAttr(::new (S.Context)
2417 ObjCNSObjectAttr(Attr.getRange(), S.Context,
2418 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanianfa23c1d2009-01-13 23:34:40 +00002419}
2420
Mike Stumpbf916502009-07-24 19:02:52 +00002421static void
Chandler Carruth1b03c872011-07-02 00:01:44 +00002422handleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Douglas Gregorf9201e02009-02-11 23:02:49 +00002423 if (Attr.getNumArgs() != 0) {
John McCall2b7baf02010-05-28 18:25:28 +00002424 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
Douglas Gregorf9201e02009-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 Han51d8c522013-01-24 16:46:58 +00002433 D->addAttr(::new (S.Context)
2434 OverloadableAttr(Attr.getRange(), S.Context,
2435 Attr.getAttributeSpellingListIndex()));
Douglas Gregorf9201e02009-02-11 23:02:49 +00002436}
2437
Chandler Carruth1b03c872011-07-02 00:01:44 +00002438static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Mike Stumpbf916502009-07-24 19:02:52 +00002439 if (!Attr.getParameterName()) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00002440 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
Chris Lattner3c73c412008-11-19 08:23:25 +00002441 << "blocks" << 1;
Steve Naroff9eae5762008-09-18 16:44:58 +00002442 return;
2443 }
Mike Stumpbf916502009-07-24 19:02:52 +00002444
Steve Naroff9eae5762008-09-18 16:44:58 +00002445 if (Attr.getNumArgs() != 0) {
Chris Lattner3c73c412008-11-19 08:23:25 +00002446 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
Steve Naroff9eae5762008-09-18 16:44:58 +00002447 return;
2448 }
Mike Stumpbf916502009-07-24 19:02:52 +00002449
Sean Huntcf807c42010-08-18 23:23:40 +00002450 BlocksAttr::BlockType type;
Chris Lattner92e62b02008-11-20 04:42:34 +00002451 if (Attr.getParameterName()->isStr("byref"))
Steve Naroff9eae5762008-09-18 16:44:58 +00002452 type = BlocksAttr::ByRef;
2453 else {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00002454 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
Chris Lattner3c73c412008-11-19 08:23:25 +00002455 << "blocks" << Attr.getParameterName();
Steve Naroff9eae5762008-09-18 16:44:58 +00002456 return;
2457 }
Mike Stumpbf916502009-07-24 19:02:52 +00002458
Michael Han51d8c522013-01-24 16:46:58 +00002459 D->addAttr(::new (S.Context)
2460 BlocksAttr(Attr.getRange(), S.Context, type,
2461 Attr.getAttributeSpellingListIndex()));
Steve Naroff9eae5762008-09-18 16:44:58 +00002462}
2463
Chandler Carruth1b03c872011-07-02 00:01:44 +00002464static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Anders Carlsson77091822008-10-05 18:05:59 +00002465 // check the attribute arguments.
2466 if (Attr.getNumArgs() > 2) {
John McCallbdc49d32011-03-02 12:15:05 +00002467 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
Anders Carlsson77091822008-10-05 18:05:59 +00002468 return;
Mike Stumpbf916502009-07-24 19:02:52 +00002469 }
2470
John McCall3323fad2011-09-09 07:56:05 +00002471 unsigned sentinel = 0;
Anders Carlsson77091822008-10-05 18:05:59 +00002472 if (Attr.getNumArgs() > 0) {
Peter Collingbourne7a730022010-11-23 20:45:58 +00002473 Expr *E = Attr.getArg(0);
Anders Carlsson77091822008-10-05 18:05:59 +00002474 llvm::APSInt Idx(32);
Douglas Gregorac06a0e2010-05-18 23:01:22 +00002475 if (E->isTypeDependent() || E->isValueDependent() ||
2476 !E->isIntegerConstantExpr(Idx, S.Context)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00002477 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner3c73c412008-11-19 08:23:25 +00002478 << "sentinel" << 1 << E->getSourceRange();
Anders Carlsson77091822008-10-05 18:05:59 +00002479 return;
2480 }
Mike Stumpbf916502009-07-24 19:02:52 +00002481
John McCall3323fad2011-09-09 07:56:05 +00002482 if (Idx.isSigned() && Idx.isNegative()) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00002483 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2484 << E->getSourceRange();
Anders Carlsson77091822008-10-05 18:05:59 +00002485 return;
2486 }
John McCall3323fad2011-09-09 07:56:05 +00002487
2488 sentinel = Idx.getZExtValue();
Anders Carlsson77091822008-10-05 18:05:59 +00002489 }
2490
John McCall3323fad2011-09-09 07:56:05 +00002491 unsigned nullPos = 0;
Anders Carlsson77091822008-10-05 18:05:59 +00002492 if (Attr.getNumArgs() > 1) {
Peter Collingbourne7a730022010-11-23 20:45:58 +00002493 Expr *E = Attr.getArg(1);
Anders Carlsson77091822008-10-05 18:05:59 +00002494 llvm::APSInt Idx(32);
Douglas Gregorac06a0e2010-05-18 23:01:22 +00002495 if (E->isTypeDependent() || E->isValueDependent() ||
2496 !E->isIntegerConstantExpr(Idx, S.Context)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00002497 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner3c73c412008-11-19 08:23:25 +00002498 << "sentinel" << 2 << E->getSourceRange();
Anders Carlsson77091822008-10-05 18:05:59 +00002499 return;
2500 }
2501 nullPos = Idx.getZExtValue();
Mike Stumpbf916502009-07-24 19:02:52 +00002502
John McCall3323fad2011-09-09 07:56:05 +00002503 if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
Anders Carlsson77091822008-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 Lattnerfa25bbb2008-11-19 05:08:23 +00002506 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
2507 << E->getSourceRange();
Anders Carlsson77091822008-10-05 18:05:59 +00002508 return;
2509 }
2510 }
2511
Chandler Carruth87c44602011-07-01 23:49:12 +00002512 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
John McCall3323fad2011-09-09 07:56:05 +00002513 const FunctionType *FT = FD->getType()->castAs<FunctionType>();
Chris Lattner897cd902009-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 Stumpbf916502009-07-24 19:02:52 +00002518
Chris Lattner897cd902009-03-17 23:03:47 +00002519 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
Fariborz Jahanian3bba33d2009-05-15 21:18:04 +00002520 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
Anders Carlsson77091822008-10-05 18:05:59 +00002521 return;
Mike Stumpbf916502009-07-24 19:02:52 +00002522 }
Chandler Carruth87c44602011-07-01 23:49:12 +00002523 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
Anders Carlsson77091822008-10-05 18:05:59 +00002524 if (!MD->isVariadic()) {
Fariborz Jahanian3bba33d2009-05-15 21:18:04 +00002525 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
Anders Carlsson77091822008-10-05 18:05:59 +00002526 return;
Fariborz Jahanian2f7c3922009-05-14 20:53:39 +00002527 }
Eli Friedmana0b2ba12012-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 Carruth87c44602011-07-01 23:49:12 +00002533 } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
Fariborz Jahanian2f7c3922009-05-14 20:53:39 +00002534 QualType Ty = V->getType();
Fariborz Jahaniandaf04152009-05-15 20:33:25 +00002535 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
Chandler Carruth87c44602011-07-01 23:49:12 +00002536 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
Eric Christopherf48f3672010-12-01 22:13:54 +00002537 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
Fariborz Jahanian2f7c3922009-05-14 20:53:39 +00002538 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
Fariborz Jahanian3bba33d2009-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 Jahanian2f7c3922009-05-14 20:53:39 +00002541 return;
2542 }
Mike Stumpac5fc7c2009-08-04 21:02:39 +00002543 } else {
Fariborz Jahanian2f7c3922009-05-14 20:53:39 +00002544 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00002545 << Attr.getName() << ExpectedFunctionMethodOrBlock;
Fariborz Jahanian2f7c3922009-05-14 20:53:39 +00002546 return;
2547 }
Anders Carlsson77091822008-10-05 18:05:59 +00002548 } else {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00002549 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00002550 << Attr.getName() << ExpectedFunctionMethodOrBlock;
Anders Carlsson77091822008-10-05 18:05:59 +00002551 return;
2552 }
Michael Han51d8c522013-01-24 16:46:58 +00002553 D->addAttr(::new (S.Context)
2554 SentinelAttr(Attr.getRange(), S.Context, sentinel, nullPos,
2555 Attr.getAttributeSpellingListIndex()));
Anders Carlsson77091822008-10-05 18:05:59 +00002556}
2557
Chandler Carruth1b03c872011-07-02 00:01:44 +00002558static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner026dc962009-02-14 07:37:35 +00002559 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00002560 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattner026dc962009-02-14 07:37:35 +00002561 return;
Chris Lattner026dc962009-02-14 07:37:35 +00002562
Kaelyn Uhrain51ceb7b2012-11-12 23:48:05 +00002563 if (!isFunction(D) && !isa<ObjCMethodDecl>(D) && !isa<CXXRecordDecl>(D)) {
Chris Lattner026dc962009-02-14 07:37:35 +00002564 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
Kaelyn Uhraind449c792012-11-13 00:18:47 +00002565 << Attr.getName() << ExpectedFunctionMethodOrClass;
Chris Lattner026dc962009-02-14 07:37:35 +00002566 return;
2567 }
Mike Stumpbf916502009-07-24 19:02:52 +00002568
Fariborz Jahanianf0317742010-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 Lopesf8577982009-12-22 23:59:52 +00002572 return;
2573 }
Fariborz Jahanianf0317742010-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 Han51d8c522013-01-24 16:46:58 +00002581 D->addAttr(::new (S.Context)
2582 WarnUnusedResultAttr(Attr.getRange(), S.Context,
2583 Attr.getAttributeSpellingListIndex()));
Chris Lattner026dc962009-02-14 07:37:35 +00002584}
2585
Chandler Carruth1b03c872011-07-02 00:01:44 +00002586static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner6b6b5372008-06-26 18:38:35 +00002587 // check the attribute arguments.
Chandler Carruth87c44602011-07-01 23:49:12 +00002588 if (Attr.hasParameterOrArguments()) {
2589 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
Chris Lattner6b6b5372008-06-26 18:38:35 +00002590 return;
2591 }
Daniel Dunbar6e775db2009-03-06 06:39:57 +00002592
Chandler Carruth87c44602011-07-01 23:49:12 +00002593 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
Fariborz Jahanian13c7fcc2011-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 Carruth87c44602011-07-01 23:49:12 +00002598 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2599 << Attr.getName() << ExpectedVariableOrFunction;
Fariborz Jahanianf23ecd92009-07-16 01:12:24 +00002600 return;
2601 }
2602
Chandler Carruth87c44602011-07-01 23:49:12 +00002603 NamedDecl *nd = cast<NamedDecl>(D);
John McCall332bb2a2011-02-08 22:35:49 +00002604
Michael Han51d8c522013-01-24 16:46:58 +00002605 nd->addAttr(::new (S.Context)
2606 WeakAttr(Attr.getRange(), S.Context,
2607 Attr.getAttributeSpellingListIndex()));
Chris Lattner6b6b5372008-06-26 18:38:35 +00002608}
2609
Chandler Carruth1b03c872011-07-02 00:01:44 +00002610static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar6e775db2009-03-06 06:39:57 +00002611 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00002612 if (!checkAttributeNumArgs(S, Attr, 0))
Daniel Dunbar6e775db2009-03-06 06:39:57 +00002613 return;
Chandler Carruth1731e202011-07-11 23:30:35 +00002614
Daniel Dunbar6e775db2009-03-06 06:39:57 +00002615
2616 // weak_import only applies to variable & function declarations.
2617 bool isDef = false;
Douglas Gregor0a0d2b12011-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 Gregordef86312011-03-23 13:27:51 +00002623 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
Douglas Gregorbcfd1f52011-09-02 00:18:52 +00002624 (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
Fariborz Jahanian90eed212011-10-26 23:59:12 +00002625 (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
Douglas Gregordef86312011-03-23 13:27:51 +00002626 // Nothing to warn about here.
2627 } else
Fariborz Jahanianc0349742010-04-13 20:22:35 +00002628 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00002629 << Attr.getName() << ExpectedVariableOrFunction;
Daniel Dunbar6e775db2009-03-06 06:39:57 +00002630
Daniel Dunbar6e775db2009-03-06 06:39:57 +00002631 return;
2632 }
2633
Michael Han51d8c522013-01-24 16:46:58 +00002634 D->addAttr(::new (S.Context)
2635 WeakImportAttr(Attr.getRange(), S.Context,
2636 Attr.getAttributeSpellingListIndex()));
Daniel Dunbar6e775db2009-03-06 06:39:57 +00002637}
2638
Tanya Lattner0df579e2012-07-09 22:06:01 +00002639// Handles reqd_work_group_size and work_group_size_hint.
2640static void handleWorkGroupSize(Sema &S, Decl *D,
Nick Lewycky4ae89bc2012-07-24 01:31:55 +00002641 const AttributeList &Attr) {
Tanya Lattner0df579e2012-07-09 22:06:01 +00002642 assert(Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize
2643 || Attr.getKind() == AttributeList::AT_WorkGroupSizeHint);
2644
Nate Begeman6f3d8382009-06-26 06:32:41 +00002645 // Attribute has 3 arguments.
Tanya Lattner0df579e2012-07-09 22:06:01 +00002646 if (!checkAttributeNumArgs(S, Attr, 3)) return;
Nate Begeman6f3d8382009-06-26 06:32:41 +00002647
2648 unsigned WGSize[3];
2649 for (unsigned i = 0; i < 3; ++i) {
Peter Collingbourne7a730022010-11-23 20:45:58 +00002650 Expr *E = Attr.getArg(i);
Nate Begeman6f3d8382009-06-26 06:32:41 +00002651 llvm::APSInt ArgNum(32);
Douglas Gregorac06a0e2010-05-18 23:01:22 +00002652 if (E->isTypeDependent() || E->isValueDependent() ||
2653 !E->isIntegerConstantExpr(ArgNum, S.Context)) {
Nate Begeman6f3d8382009-06-26 06:32:41 +00002654 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
Tanya Lattner0df579e2012-07-09 22:06:01 +00002655 << Attr.getName()->getName() << E->getSourceRange();
Nate Begeman6f3d8382009-06-26 06:32:41 +00002656 return;
2657 }
2658 WGSize[i] = (unsigned) ArgNum.getZExtValue();
2659 }
Tanya Lattner0df579e2012-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 Han51d8c522013-01-24 16:46:58 +00002686 WGSize[0], WGSize[1], WGSize[2],
2687 Attr.getAttributeSpellingListIndex()));
Tanya Lattner0df579e2012-07-09 22:06:01 +00002688 else
2689 D->addAttr(::new (S.Context)
2690 WorkGroupSizeHintAttr(Attr.getRange(), S.Context,
Michael Han51d8c522013-01-24 16:46:58 +00002691 WGSize[0], WGSize[1], WGSize[2],
2692 Attr.getAttributeSpellingListIndex()));
Nate Begeman6f3d8382009-06-26 06:32:41 +00002693}
2694
Rafael Espindola599f1b72012-05-13 03:25:18 +00002695SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
Michael Han51d8c522013-01-24 16:46:58 +00002696 StringRef Name,
2697 unsigned AttrSpellingListIndex) {
Rafael Espindola420efd82012-05-13 02:42:42 +00002698 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
2699 if (ExistingAttr->getName() == Name)
Rafael Espindola599f1b72012-05-13 03:25:18 +00002700 return NULL;
Rafael Espindola420efd82012-05-13 02:42:42 +00002701 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section);
2702 Diag(Range.getBegin(), diag::note_previous_attribute);
Rafael Espindola599f1b72012-05-13 03:25:18 +00002703 return NULL;
Rafael Espindola420efd82012-05-13 02:42:42 +00002704 }
Michael Han51d8c522013-01-24 16:46:58 +00002705 return ::new (Context) SectionAttr(Range, Context, Name,
2706 AttrSpellingListIndex);
Rafael Espindola420efd82012-05-13 02:42:42 +00002707}
2708
Chandler Carruth1b03c872011-07-02 00:01:44 +00002709static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Daniel Dunbar17f194f2009-02-12 17:28:23 +00002710 // Attribute has no arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00002711 if (!checkAttributeNumArgs(S, Attr, 1))
Daniel Dunbar17f194f2009-02-12 17:28:23 +00002712 return;
Daniel Dunbar17f194f2009-02-12 17:28:23 +00002713
2714 // Make sure that there is a string literal as the sections's single
2715 // argument.
Peter Collingbourne7a730022010-11-23 20:45:58 +00002716 Expr *ArgExpr = Attr.getArg(0);
Chris Lattner797c3c42009-08-10 19:03:04 +00002717 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
Daniel Dunbar17f194f2009-02-12 17:28:23 +00002718 if (!SE) {
Chris Lattner797c3c42009-08-10 19:03:04 +00002719 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
Daniel Dunbar17f194f2009-02-12 17:28:23 +00002720 return;
2721 }
Mike Stump1eb44332009-09-09 15:08:12 +00002722
Chris Lattner797c3c42009-08-10 19:03:04 +00002723 // If the target wants to validate the section specifier, make it happen.
Douglas Gregorbcfd1f52011-09-02 00:18:52 +00002724 std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString());
Chris Lattnera1e1dc72010-01-12 20:58:53 +00002725 if (!Error.empty()) {
2726 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
2727 << Error;
Chris Lattner797c3c42009-08-10 19:03:04 +00002728 return;
2729 }
Mike Stump1eb44332009-09-09 15:08:12 +00002730
Chris Lattnera1e1dc72010-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 Han51d8c522013-01-24 16:46:58 +00002736
2737 unsigned Index = Attr.getAttributeSpellingListIndex();
Rafael Espindola599f1b72012-05-13 03:25:18 +00002738 SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(),
Michael Han51d8c522013-01-24 16:46:58 +00002739 SE->getString(), Index);
Rafael Espindola599f1b72012-05-13 03:25:18 +00002740 if (NewAttr)
2741 D->addAttr(NewAttr);
Daniel Dunbar17f194f2009-02-12 17:28:23 +00002742}
2743
Chris Lattner6b6b5372008-06-26 18:38:35 +00002744
Chandler Carruth1b03c872011-07-02 00:01:44 +00002745static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner6b6b5372008-06-26 18:38:35 +00002746 // check the attribute arguments.
Ted Kremenek831efae2011-04-15 05:49:29 +00002747 if (Attr.hasParameterOrArguments()) {
Chris Lattner3c73c412008-11-19 08:23:25 +00002748 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
Chris Lattner6b6b5372008-06-26 18:38:35 +00002749 return;
2750 }
Douglas Gregorb30cd4a2011-06-15 05:45:11 +00002751
Chandler Carruth87c44602011-07-01 23:49:12 +00002752 if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
Douglas Gregorb30cd4a2011-06-15 05:45:11 +00002753 if (Existing->getLocation().isInvalid())
Argyrios Kyrtzidisffcc3102011-09-13 16:05:53 +00002754 Existing->setRange(Attr.getRange());
Douglas Gregorb30cd4a2011-06-15 05:45:11 +00002755 } else {
Michael Han51d8c522013-01-24 16:46:58 +00002756 D->addAttr(::new (S.Context)
2757 NoThrowAttr(Attr.getRange(), S.Context,
2758 Attr.getAttributeSpellingListIndex()));
Douglas Gregorb30cd4a2011-06-15 05:45:11 +00002759 }
Chris Lattner6b6b5372008-06-26 18:38:35 +00002760}
2761
Chandler Carruth1b03c872011-07-02 00:01:44 +00002762static void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Anders Carlsson232eb7d2008-10-05 23:32:53 +00002763 // check the attribute arguments.
Ted Kremenek831efae2011-04-15 05:49:29 +00002764 if (Attr.hasParameterOrArguments()) {
Chris Lattner3c73c412008-11-19 08:23:25 +00002765 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
Anders Carlsson232eb7d2008-10-05 23:32:53 +00002766 return;
2767 }
Mike Stumpbf916502009-07-24 19:02:52 +00002768
Chandler Carruth87c44602011-07-01 23:49:12 +00002769 if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
Douglas Gregorb30cd4a2011-06-15 05:45:11 +00002770 if (Existing->getLocation().isInvalid())
Argyrios Kyrtzidisffcc3102011-09-13 16:05:53 +00002771 Existing->setRange(Attr.getRange());
Douglas Gregorb30cd4a2011-06-15 05:45:11 +00002772 } else {
Michael Han51d8c522013-01-24 16:46:58 +00002773 D->addAttr(::new (S.Context)
2774 ConstAttr(Attr.getRange(), S.Context,
2775 Attr.getAttributeSpellingListIndex() ));
Douglas Gregorb30cd4a2011-06-15 05:45:11 +00002776 }
Anders Carlsson232eb7d2008-10-05 23:32:53 +00002777}
2778
Chandler Carruth1b03c872011-07-02 00:01:44 +00002779static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Anders Carlsson232eb7d2008-10-05 23:32:53 +00002780 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00002781 if (!checkAttributeNumArgs(S, Attr, 0))
Anders Carlsson232eb7d2008-10-05 23:32:53 +00002782 return;
Mike Stumpbf916502009-07-24 19:02:52 +00002783
Michael Han51d8c522013-01-24 16:46:58 +00002784 D->addAttr(::new (S.Context)
2785 PureAttr(Attr.getRange(), S.Context,
2786 Attr.getAttributeSpellingListIndex()));
Anders Carlsson232eb7d2008-10-05 23:32:53 +00002787}
2788
Chandler Carruth1b03c872011-07-02 00:01:44 +00002789static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Mike Stumpbf916502009-07-24 19:02:52 +00002790 if (!Attr.getParameterName()) {
Anders Carlssonf6e35d02009-01-31 01:16:18 +00002791 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2792 return;
2793 }
Mike Stumpbf916502009-07-24 19:02:52 +00002794
Anders Carlssonf6e35d02009-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 Stumpbf916502009-07-24 19:02:52 +00002799
Chandler Carruth87c44602011-07-01 23:49:12 +00002800 VarDecl *VD = dyn_cast<VarDecl>(D);
Mike Stumpbf916502009-07-24 19:02:52 +00002801
Anders Carlssonf6e35d02009-01-31 01:16:18 +00002802 if (!VD || !VD->hasLocalStorage()) {
2803 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
2804 return;
2805 }
Mike Stumpbf916502009-07-24 19:02:52 +00002806
Anders Carlssonf6e35d02009-01-31 01:16:18 +00002807 // Look up the function
Douglas Gregorc83c6872010-04-15 22:33:43 +00002808 // FIXME: Lookup probably isn't looking in the right place
John McCallf36e02d2009-10-09 21:13:30 +00002809 NamedDecl *CleanupDecl
Argyrios Kyrtzidisf0b0ccc2010-12-06 17:51:50 +00002810 = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
2811 Attr.getParameterLoc(), Sema::LookupOrdinaryName);
Anders Carlssonf6e35d02009-01-31 01:16:18 +00002812 if (!CleanupDecl) {
Argyrios Kyrtzidisf0b0ccc2010-12-06 17:51:50 +00002813 S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
Anders Carlssonf6e35d02009-01-31 01:16:18 +00002814 Attr.getParameterName();
2815 return;
2816 }
Mike Stumpbf916502009-07-24 19:02:52 +00002817
Anders Carlssonf6e35d02009-01-31 01:16:18 +00002818 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
2819 if (!FD) {
Argyrios Kyrtzidisf0b0ccc2010-12-06 17:51:50 +00002820 S.Diag(Attr.getParameterLoc(),
2821 diag::err_attribute_cleanup_arg_not_function)
2822 << Attr.getParameterName();
Anders Carlssonf6e35d02009-01-31 01:16:18 +00002823 return;
2824 }
2825
Anders Carlssonf6e35d02009-01-31 01:16:18 +00002826 if (FD->getNumParams() != 1) {
Argyrios Kyrtzidisf0b0ccc2010-12-06 17:51:50 +00002827 S.Diag(Attr.getParameterLoc(),
2828 diag::err_attribute_cleanup_func_must_take_one_arg)
2829 << Attr.getParameterName();
Anders Carlssonf6e35d02009-01-31 01:16:18 +00002830 return;
2831 }
Mike Stumpbf916502009-07-24 19:02:52 +00002832
Anders Carlsson89941c12009-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 Gregorb608b982011-01-28 02:26:04 +00002837 if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2838 ParamTy, Ty) != Sema::Compatible) {
Argyrios Kyrtzidisf0b0ccc2010-12-06 17:51:50 +00002839 S.Diag(Attr.getParameterLoc(),
Anders Carlsson89941c12009-02-07 23:16:50 +00002840 diag::err_attribute_cleanup_func_arg_incompatible_type) <<
2841 Attr.getParameterName() << ParamTy << Ty;
2842 return;
2843 }
Mike Stumpbf916502009-07-24 19:02:52 +00002844
Michael Han51d8c522013-01-24 16:46:58 +00002845 D->addAttr(::new (S.Context)
2846 CleanupAttr(Attr.getRange(), S.Context, FD,
2847 Attr.getAttributeSpellingListIndex()));
Eli Friedman5f2987c2012-02-02 03:46:19 +00002848 S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
Anders Carlssonf6e35d02009-01-31 01:16:18 +00002849}
2850
Mike Stumpbf916502009-07-24 19:02:52 +00002851/// Handle __attribute__((format_arg((idx)))) attribute based on
Bill Wendlingad017fa2012-12-20 19:22:21 +00002852/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Chandler Carruth1b03c872011-07-02 00:01:44 +00002853static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruth1731e202011-07-11 23:30:35 +00002854 if (!checkAttributeNumArgs(S, Attr, 1))
Fariborz Jahanian5b160922009-05-20 17:41:43 +00002855 return;
Chandler Carruth1731e202011-07-11 23:30:35 +00002856
Chandler Carruth87c44602011-07-01 23:49:12 +00002857 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
Fariborz Jahanian5b160922009-05-20 17:41:43 +00002858 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00002859 << Attr.getName() << ExpectedFunction;
Fariborz Jahanian5b160922009-05-20 17:41:43 +00002860 return;
2861 }
Chandler Carruth07d7e7a2010-11-16 08:35:43 +00002862
2863 // In C++ the implicit 'this' function parameter also counts, and they are
2864 // counted from one.
Chandler Carruth87c44602011-07-01 23:49:12 +00002865 bool HasImplicitThisParam = isInstanceMethod(D);
2866 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
Fariborz Jahanian5b160922009-05-20 17:41:43 +00002867 unsigned FirstIdx = 1;
Chandler Carruth07d7e7a2010-11-16 08:35:43 +00002868
Fariborz Jahanian5b160922009-05-20 17:41:43 +00002869 // checks for the 2nd argument
Peter Collingbourne7a730022010-11-23 20:45:58 +00002870 Expr *IdxExpr = Attr.getArg(0);
Fariborz Jahanian5b160922009-05-20 17:41:43 +00002871 llvm::APSInt Idx(32);
Douglas Gregorac06a0e2010-05-18 23:01:22 +00002872 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
2873 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
Fariborz Jahanian5b160922009-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 Stumpbf916502009-07-24 19:02:52 +00002878
Fariborz Jahanian5b160922009-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 Stumpbf916502009-07-24 19:02:52 +00002884
Fariborz Jahanian5b160922009-05-20 17:41:43 +00002885 unsigned ArgIdx = Idx.getZExtValue() - 1;
Mike Stumpbf916502009-07-24 19:02:52 +00002886
Chandler Carruth07d7e7a2010-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 Jahanian5b160922009-05-20 17:41:43 +00002896 // make sure the format string is really a string
Chandler Carruth87c44602011-07-01 23:49:12 +00002897 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
Mike Stumpbf916502009-07-24 19:02:52 +00002898
Fariborz Jahanian5b160922009-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 Kremenek6217b802009-07-29 21:53:49 +00002903 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
Fariborz Jahanian5b160922009-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 Stumpbf916502009-07-24 19:02:52 +00002906 << (not_nsstring_type ? "a string type" : "an NSString")
Fariborz Jahanian5b160922009-05-20 17:41:43 +00002907 << IdxExpr->getSourceRange();
2908 return;
Mike Stumpbf916502009-07-24 19:02:52 +00002909 }
Chandler Carruth87c44602011-07-01 23:49:12 +00002910 Ty = getFunctionOrMethodResultType(D);
Fariborz Jahanian5b160922009-05-20 17:41:43 +00002911 if (!isNSStringType(Ty, S.Context) &&
2912 !isCFStringType(Ty, S.Context) &&
2913 (!Ty->isPointerType() ||
Ted Kremenek6217b802009-07-29 21:53:49 +00002914 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
Fariborz Jahanian5b160922009-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 Stumpbf916502009-07-24 19:02:52 +00002917 << (not_nsstring_type ? "string type" : "NSString")
Fariborz Jahanian5b160922009-05-20 17:41:43 +00002918 << IdxExpr->getSourceRange();
2919 return;
Mike Stumpbf916502009-07-24 19:02:52 +00002920 }
2921
Michael Han51d8c522013-01-24 16:46:58 +00002922 D->addAttr(::new (S.Context)
2923 FormatArgAttr(Attr.getRange(), S.Context, Idx.getZExtValue(),
2924 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanian5b160922009-05-20 17:41:43 +00002925}
2926
Daniel Dunbar2b0d9a22009-10-18 02:09:17 +00002927enum FormatAttrKind {
2928 CFStringFormat,
2929 NSStringFormat,
2930 StrftimeFormat,
2931 SupportedFormat,
Chris Lattner3c989022010-03-22 21:08:50 +00002932 IgnoredFormat,
Daniel Dunbar2b0d9a22009-10-18 02:09:17 +00002933 InvalidFormat
2934};
2935
2936/// getFormatAttrKind - Map from format attribute names to supported format
2937/// types.
Chris Lattner5f9e2722011-07-23 10:55:15 +00002938static FormatAttrKind getFormatAttrKind(StringRef Format) {
Benjamin Kramerc51bb992012-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 Dunbar2b0d9a22009-10-18 02:09:17 +00002944
Benjamin Kramerc51bb992012-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 Dunbar2b0d9a22009-10-18 02:09:17 +00002949
Benjamin Kramerc51bb992012-05-16 12:44:25 +00002950 .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
2951 .Default(InvalidFormat);
Daniel Dunbar2b0d9a22009-10-18 02:09:17 +00002952}
2953
Fariborz Jahanian521f12d2010-06-18 21:44:06 +00002954/// Handle __attribute__((init_priority(priority))) attributes based on
Bill Wendlingad017fa2012-12-20 19:22:21 +00002955/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
Chandler Carruth1b03c872011-07-02 00:01:44 +00002956static void handleInitPriorityAttr(Sema &S, Decl *D,
2957 const AttributeList &Attr) {
David Blaikie4e4d0842012-03-11 07:00:24 +00002958 if (!S.getLangOpts().CPlusPlus) {
Fariborz Jahanian521f12d2010-06-18 21:44:06 +00002959 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2960 return;
2961 }
2962
Chandler Carruth87c44602011-07-01 23:49:12 +00002963 if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
Fariborz Jahanianb9d5c222010-06-18 23:14:53 +00002964 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2965 Attr.setInvalid();
2966 return;
2967 }
Chandler Carruth87c44602011-07-01 23:49:12 +00002968 QualType T = dyn_cast<VarDecl>(D)->getType();
Fariborz Jahanianb9d5c222010-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 Jahanian521f12d2010-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 Collingbourne7a730022010-11-23 20:45:58 +00002982 Expr *priorityExpr = Attr.getArg(0);
Fariborz Jahanianb9d5c222010-06-18 23:14:53 +00002983
Fariborz Jahanian521f12d2010-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 Jahanian9f967c52010-06-21 18:45:05 +00002992 unsigned prioritynum = priority.getZExtValue();
Fariborz Jahanian521f12d2010-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 Han51d8c522013-01-24 16:46:58 +00002999 D->addAttr(::new (S.Context)
3000 InitPriorityAttr(Attr.getRange(), S.Context, prioritynum,
3001 Attr.getAttributeSpellingListIndex()));
Fariborz Jahanian521f12d2010-06-18 21:44:06 +00003002}
3003
Rafael Espindola599f1b72012-05-13 03:25:18 +00003004FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
Michael Han51d8c522013-01-24 16:46:58 +00003005 int FormatIdx, int FirstArg,
3006 unsigned AttrSpellingListIndex) {
Rafael Espindolabf9da1f2012-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 Espindola599f1b72012-05-13 03:25:18 +00003020 return NULL;
Rafael Espindolabf9da1f2012-05-11 00:36:07 +00003021 }
3022 }
3023
Michael Han51d8c522013-01-24 16:46:58 +00003024 return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, FirstArg,
3025 AttrSpellingListIndex);
Rafael Espindolabf9da1f2012-05-11 00:36:07 +00003026}
3027
Mike Stumpbf916502009-07-24 19:02:52 +00003028/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
Bill Wendlingad017fa2012-12-20 19:22:21 +00003029/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Chandler Carruth1b03c872011-07-02 00:01:44 +00003030static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner6b6b5372008-06-26 18:38:35 +00003031
Chris Lattner545dd342008-06-28 23:36:30 +00003032 if (!Attr.getParameterName()) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003033 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
Chris Lattner3c73c412008-11-19 08:23:25 +00003034 << "format" << 1;
Chris Lattner6b6b5372008-06-26 18:38:35 +00003035 return;
3036 }
3037
Chris Lattner545dd342008-06-28 23:36:30 +00003038 if (Attr.getNumArgs() != 2) {
Chris Lattner3c73c412008-11-19 08:23:25 +00003039 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
Chris Lattner6b6b5372008-06-26 18:38:35 +00003040 return;
3041 }
3042
Chandler Carruth87c44602011-07-01 23:49:12 +00003043 if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003044 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00003045 << Attr.getName() << ExpectedFunction;
Chris Lattner6b6b5372008-06-26 18:38:35 +00003046 return;
3047 }
3048
Chandler Carruth07d7e7a2010-11-16 08:35:43 +00003049 // In C++ the implicit 'this' function parameter also counts, and they are
3050 // counted from one.
Chandler Carruth87c44602011-07-01 23:49:12 +00003051 bool HasImplicitThisParam = isInstanceMethod(D);
3052 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
Chris Lattner6b6b5372008-06-26 18:38:35 +00003053 unsigned FirstIdx = 1;
3054
Chris Lattner5f9e2722011-07-23 10:55:15 +00003055 StringRef Format = Attr.getParameterName()->getName();
Chris Lattner6b6b5372008-06-26 18:38:35 +00003056
3057 // Normalize the argument, __foo__ becomes foo.
Daniel Dunbar2b0d9a22009-10-18 02:09:17 +00003058 if (Format.startswith("__") && Format.endswith("__"))
3059 Format = Format.substr(2, Format.size() - 4);
Chris Lattner6b6b5372008-06-26 18:38:35 +00003060
Daniel Dunbar2b0d9a22009-10-18 02:09:17 +00003061 // Check for supported formats.
3062 FormatAttrKind Kind = getFormatAttrKind(Format);
Chris Lattner3c989022010-03-22 21:08:50 +00003063
3064 if (Kind == IgnoredFormat)
3065 return;
3066
Daniel Dunbar2b0d9a22009-10-18 02:09:17 +00003067 if (Kind == InvalidFormat) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003068 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
Daniel Dunbar01eb9b92009-10-18 21:17:35 +00003069 << "format" << Attr.getParameterName()->getName();
Chris Lattner6b6b5372008-06-26 18:38:35 +00003070 return;
3071 }
3072
3073 // checks for the 2nd argument
Peter Collingbourne7a730022010-11-23 20:45:58 +00003074 Expr *IdxExpr = Attr.getArg(0);
Chris Lattner803d0802008-06-29 00:43:07 +00003075 llvm::APSInt Idx(32);
Douglas Gregorac06a0e2010-05-18 23:01:22 +00003076 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
3077 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003078 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner3c73c412008-11-19 08:23:25 +00003079 << "format" << 2 << IdxExpr->getSourceRange();
Chris Lattner6b6b5372008-06-26 18:38:35 +00003080 return;
3081 }
3082
3083 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003084 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
Chris Lattner3c73c412008-11-19 08:23:25 +00003085 << "format" << 2 << IdxExpr->getSourceRange();
Chris Lattner6b6b5372008-06-26 18:38:35 +00003086 return;
3087 }
3088
3089 // FIXME: Do we need to bounds check?
3090 unsigned ArgIdx = Idx.getZExtValue() - 1;
Mike Stumpbf916502009-07-24 19:02:52 +00003091
Sebastian Redl4a2614e2009-11-17 18:02:24 +00003092 if (HasImplicitThisParam) {
3093 if (ArgIdx == 0) {
Chandler Carruth07d7e7a2010-11-16 08:35:43 +00003094 S.Diag(Attr.getLoc(),
3095 diag::err_format_attribute_implicit_this_format_string)
3096 << IdxExpr->getSourceRange();
Sebastian Redl4a2614e2009-11-17 18:02:24 +00003097 return;
3098 }
3099 ArgIdx--;
3100 }
Mike Stump1eb44332009-09-09 15:08:12 +00003101
Chris Lattner6b6b5372008-06-26 18:38:35 +00003102 // make sure the format string is really a string
Chandler Carruth87c44602011-07-01 23:49:12 +00003103 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
Chris Lattner6b6b5372008-06-26 18:38:35 +00003104
Daniel Dunbar2b0d9a22009-10-18 02:09:17 +00003105 if (Kind == CFStringFormat) {
Daniel Dunbar085e8f72008-09-26 03:32:58 +00003106 if (!isCFStringType(Ty, S.Context)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003107 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
3108 << "a CFString" << IdxExpr->getSourceRange();
Daniel Dunbar085e8f72008-09-26 03:32:58 +00003109 return;
3110 }
Daniel Dunbar2b0d9a22009-10-18 02:09:17 +00003111 } else if (Kind == NSStringFormat) {
Mike Stump390b4cc2009-05-16 07:39:55 +00003112 // FIXME: do we need to check if the type is NSString*? What are the
3113 // semantics?
Chris Lattner803d0802008-06-29 00:43:07 +00003114 if (!isNSStringType(Ty, S.Context)) {
Mike Stump390b4cc2009-05-16 07:39:55 +00003115 // FIXME: Should highlight the actual expression that has the wrong type.
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003116 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
3117 << "an NSString" << IdxExpr->getSourceRange();
Chris Lattner6b6b5372008-06-26 18:38:35 +00003118 return;
Mike Stumpbf916502009-07-24 19:02:52 +00003119 }
Chris Lattner6b6b5372008-06-26 18:38:35 +00003120 } else if (!Ty->isPointerType() ||
Ted Kremenek6217b802009-07-29 21:53:49 +00003121 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
Mike Stump390b4cc2009-05-16 07:39:55 +00003122 // FIXME: Should highlight the actual expression that has the wrong type.
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003123 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
3124 << "a string type" << IdxExpr->getSourceRange();
Chris Lattner6b6b5372008-06-26 18:38:35 +00003125 return;
3126 }
3127
3128 // check the 3rd argument
Peter Collingbourne7a730022010-11-23 20:45:58 +00003129 Expr *FirstArgExpr = Attr.getArg(1);
Chris Lattner803d0802008-06-29 00:43:07 +00003130 llvm::APSInt FirstArg(32);
Douglas Gregorac06a0e2010-05-18 23:01:22 +00003131 if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
3132 !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003133 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
Chris Lattner3c73c412008-11-19 08:23:25 +00003134 << "format" << 3 << FirstArgExpr->getSourceRange();
Chris Lattner6b6b5372008-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 Carruth87c44602011-07-01 23:49:12 +00003140 if (isFunctionOrMethodVariadic(D)) {
Chris Lattner6b6b5372008-06-26 18:38:35 +00003141 ++NumArgs; // +1 for ...
3142 } else {
Chandler Carruth87c44602011-07-01 23:49:12 +00003143 S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
Chris Lattner6b6b5372008-06-26 18:38:35 +00003144 return;
3145 }
3146 }
3147
Chris Lattner3c73c412008-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 Dunbar2b0d9a22009-10-18 02:09:17 +00003150 if (Kind == StrftimeFormat) {
Chris Lattner6b6b5372008-06-26 18:38:35 +00003151 if (FirstArg != 0) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003152 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
3153 << FirstArgExpr->getSourceRange();
Chris Lattner6b6b5372008-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 Lattnerfa25bbb2008-11-19 05:08:23 +00003158 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
Chris Lattner3c73c412008-11-19 08:23:25 +00003159 << "format" << 3 << FirstArgExpr->getSourceRange();
Chris Lattner6b6b5372008-06-26 18:38:35 +00003160 return;
3161 }
3162
Rafael Espindola599f1b72012-05-13 03:25:18 +00003163 FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format,
3164 Idx.getZExtValue(),
Michael Han51d8c522013-01-24 16:46:58 +00003165 FirstArg.getZExtValue(),
3166 Attr.getAttributeSpellingListIndex());
Rafael Espindola599f1b72012-05-13 03:25:18 +00003167 if (NewAttr)
3168 D->addAttr(NewAttr);
Chris Lattner6b6b5372008-06-26 18:38:35 +00003169}
3170
Chandler Carruth1b03c872011-07-02 00:01:44 +00003171static void handleTransparentUnionAttr(Sema &S, Decl *D,
3172 const AttributeList &Attr) {
Chris Lattner6b6b5372008-06-26 18:38:35 +00003173 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00003174 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattner6b6b5372008-06-26 18:38:35 +00003175 return;
Chandler Carruth1731e202011-07-11 23:30:35 +00003176
Chris Lattner6b6b5372008-06-26 18:38:35 +00003177
Douglas Gregor0c74e8a2009-04-29 22:16:16 +00003178 // Try to find the underlying union declaration.
3179 RecordDecl *RD = 0;
Chandler Carruth87c44602011-07-01 23:49:12 +00003180 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
Douglas Gregor0c74e8a2009-04-29 22:16:16 +00003181 if (TD && TD->getUnderlyingType()->isUnionType())
3182 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
3183 else
Chandler Carruth87c44602011-07-01 23:49:12 +00003184 RD = dyn_cast<RecordDecl>(D);
Douglas Gregor0c74e8a2009-04-29 22:16:16 +00003185
3186 if (!RD || !RD->isUnion()) {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003187 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00003188 << Attr.getName() << ExpectedUnion;
Chris Lattner6b6b5372008-06-26 18:38:35 +00003189 return;
3190 }
3191
John McCall5e1cdac2011-10-07 06:10:15 +00003192 if (!RD->isCompleteDefinition()) {
Mike Stumpbf916502009-07-24 19:02:52 +00003193 S.Diag(Attr.getLoc(),
Douglas Gregor0c74e8a2009-04-29 22:16:16 +00003194 diag::warn_transparent_union_attribute_not_definition);
3195 return;
3196 }
Chris Lattner6b6b5372008-06-26 18:38:35 +00003197
Argyrios Kyrtzidis17945a02009-06-30 02:36:12 +00003198 RecordDecl::field_iterator Field = RD->field_begin(),
3199 FieldEnd = RD->field_end();
Douglas Gregor0c74e8a2009-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 Friedmanbc887452008-09-02 05:19:23 +00003204
David Blaikie581deb32012-06-06 20:45:41 +00003205 FieldDecl *FirstField = *Field;
Douglas Gregor0c74e8a2009-04-29 22:16:16 +00003206 QualType FirstType = FirstField->getType();
Douglas Gregor90cd6722010-06-30 17:24:13 +00003207 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
Mike Stumpbf916502009-07-24 19:02:52 +00003208 S.Diag(FirstField->getLocation(),
Douglas Gregor90cd6722010-06-30 17:24:13 +00003209 diag::warn_transparent_union_attribute_floating)
3210 << FirstType->isVectorType() << FirstType;
Douglas Gregor0c74e8a2009-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 Stumpbf916502009-07-24 19:02:52 +00003222 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
Douglas Gregor0c74e8a2009-04-29 22:16:16 +00003223 : S.Context.getTypeAlign(FieldType);
Mike Stumpbf916502009-07-24 19:02:52 +00003224 S.Diag(Field->getLocation(),
Douglas Gregor0c74e8a2009-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 Stumpbf916502009-07-24 19:02:52 +00003228 S.Diag(FirstField->getLocation(),
Douglas Gregor0c74e8a2009-04-29 22:16:16 +00003229 diag::note_transparent_union_first_field_size_align)
3230 << isSize << FirstBits;
Eli Friedmanbc887452008-09-02 05:19:23 +00003231 return;
3232 }
3233 }
3234
Michael Han51d8c522013-01-24 16:46:58 +00003235 RD->addAttr(::new (S.Context)
3236 TransparentUnionAttr(Attr.getRange(), S.Context,
3237 Attr.getAttributeSpellingListIndex()));
Chris Lattner6b6b5372008-06-26 18:38:35 +00003238}
3239
Chandler Carruth1b03c872011-07-02 00:01:44 +00003240static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner6b6b5372008-06-26 18:38:35 +00003241 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00003242 if (!checkAttributeNumArgs(S, Attr, 1))
Chris Lattner6b6b5372008-06-26 18:38:35 +00003243 return;
Chandler Carruth1731e202011-07-11 23:30:35 +00003244
Peter Collingbourne7a730022010-11-23 20:45:58 +00003245 Expr *ArgExpr = Attr.getArg(0);
Chris Lattner797c3c42009-08-10 19:03:04 +00003246 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
Mike Stumpbf916502009-07-24 19:02:52 +00003247
Chris Lattner6b6b5372008-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 Lattner797c3c42009-08-10 19:03:04 +00003251 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
Chris Lattner6b6b5372008-06-26 18:38:35 +00003252 return;
3253 }
Julien Lerouge77f68bb2011-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 Han51d8c522013-01-24 16:46:58 +00003262
3263 D->addAttr(::new (S.Context)
3264 AnnotateAttr(Attr.getRange(), S.Context, SE->getString(),
3265 Attr.getAttributeSpellingListIndex()));
Chris Lattner6b6b5372008-06-26 18:38:35 +00003266}
3267
Chandler Carruth1b03c872011-07-02 00:01:44 +00003268static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner6b6b5372008-06-26 18:38:35 +00003269 // check the attribute arguments.
Chris Lattner545dd342008-06-28 23:36:30 +00003270 if (Attr.getNumArgs() > 1) {
Chris Lattner3c73c412008-11-19 08:23:25 +00003271 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
Chris Lattner6b6b5372008-06-26 18:38:35 +00003272 return;
3273 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +00003274
Richard Smith4cd81c52013-01-29 09:02:09 +00003275 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
3276 // FIXME: Use a more reliable mechanism to determine how the attribute was
3277 // spelled.
3278 if (Attr.isKeywordAttribute()) {
3279 // C++11 [dcl.align]p1:
3280 // An alignment-specifier may be applied to a variable or to a class
3281 // data member, but it shall not be applied to a bit-field, a function
3282 // parameter, the formal parameter of a catch clause, or a variable
3283 // declared with the register storage class specifier. An
3284 // alignment-specifier may also be applied to the declaration of a class
3285 // or enumeration type.
3286 // C11 6.7.5/2:
3287 // An alignment attribute shall not be specified in a declaration of
3288 // a typedef, or a bit-field, or a function, or a parameter, or an
3289 // object declared with the register storage-class specifier.
3290 int DiagKind = -1;
3291 if (isa<ParmVarDecl>(D)) {
3292 DiagKind = 0;
3293 } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3294 if (VD->getStorageClass() == SC_Register)
3295 DiagKind = 1;
3296 if (VD->isExceptionVariable())
3297 DiagKind = 2;
3298 } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
3299 if (FD->isBitField())
3300 DiagKind = 3;
3301 } else if (!isa<TagDecl>(D)) {
3302 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
3303 << Attr.getName() << ExpectedVariableFunctionOrTag;
3304 return;
3305 }
3306 if (DiagKind != -1) {
3307 S.Diag(Attr.getLoc(), diag::err_alignas_attribute_wrong_decl_type)
3308 << Attr.getName() << DiagKind;
3309 return;
3310 }
3311 }
3312
3313 // FIXME: The C++11 version of this attribute should error out when it is
3314 // used to specify a weaker alignment, rather than being silently
3315 // ignored.
Chris Lattner6b6b5372008-06-26 18:38:35 +00003316
Chris Lattner545dd342008-06-28 23:36:30 +00003317 if (Attr.getNumArgs() == 0) {
Aaron Ballmanfc685ac2012-06-19 22:09:27 +00003318 D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
Michael Han51d8c522013-01-24 16:46:58 +00003319 true, 0, Attr.isDeclspecAttribute(),
3320 Attr.getAttributeSpellingListIndex()));
Chris Lattner6b6b5372008-06-26 18:38:35 +00003321 return;
Chris Lattner6b6b5372008-06-26 18:38:35 +00003322 }
Mike Stumpbf916502009-07-24 19:02:52 +00003323
Aaron Ballmanfc685ac2012-06-19 22:09:27 +00003324 S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0),
Michael Han51d8c522013-01-24 16:46:58 +00003325 Attr.isDeclspecAttribute(),
3326 Attr.getAttributeSpellingListIndex());
Chandler Carruth4ced79f2010-06-25 03:22:07 +00003327}
3328
Aaron Ballmanfc685ac2012-06-19 22:09:27 +00003329void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
Michael Han51d8c522013-01-24 16:46:58 +00003330 bool isDeclSpec, unsigned SpellingListIndex) {
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00003331 // FIXME: Handle pack-expansions here.
3332 if (DiagnoseUnexpandedParameterPack(E))
3333 return;
3334
Chandler Carruth4ced79f2010-06-25 03:22:07 +00003335 if (E->isTypeDependent() || E->isValueDependent()) {
3336 // Save dependent expressions in the AST to be instantiated.
Aaron Ballmanfc685ac2012-06-19 22:09:27 +00003337 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E,
Michael Han51d8c522013-01-24 16:46:58 +00003338 isDeclSpec, SpellingListIndex));
Chandler Carruth4ced79f2010-06-25 03:22:07 +00003339 return;
3340 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +00003341
Argyrios Kyrtzidis768d6ca2011-09-13 16:05:58 +00003342 SourceLocation AttrLoc = AttrRange.getBegin();
Sean Huntcf807c42010-08-18 23:23:40 +00003343 // FIXME: Cache the number on the Attr object?
Chris Lattner49e2d342008-06-28 23:50:44 +00003344 llvm::APSInt Alignment(32);
Douglas Gregorab41fe92012-05-04 22:38:52 +00003345 ExprResult ICE
3346 = VerifyIntegerConstantExpression(E, &Alignment,
3347 diag::err_aligned_attribute_argument_not_int,
3348 /*AllowFold*/ false);
Richard Smith282e7e62012-02-04 09:53:13 +00003349 if (ICE.isInvalid())
Chris Lattner49e2d342008-06-28 23:50:44 +00003350 return;
Daniel Dunbar396b2a22009-02-16 23:37:57 +00003351 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
Chandler Carruth4ced79f2010-06-25 03:22:07 +00003352 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
3353 << E->getSourceRange();
Daniel Dunbar396b2a22009-02-16 23:37:57 +00003354 return;
3355 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +00003356 if (isDeclSpec) {
3357 // We've already verified it's a power of 2, now let's make sure it's
3358 // 8192 or less.
3359 if (Alignment.getZExtValue() > 8192) {
3360 Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192)
3361 << E->getSourceRange();
3362 return;
3363 }
3364 }
Daniel Dunbar396b2a22009-02-16 23:37:57 +00003365
Aaron Ballmanfc685ac2012-06-19 22:09:27 +00003366 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take(),
Michael Han51d8c522013-01-24 16:46:58 +00003367 isDeclSpec, SpellingListIndex));
Sean Huntcf807c42010-08-18 23:23:40 +00003368}
3369
Aaron Ballmanfc685ac2012-06-19 22:09:27 +00003370void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
Richard Smith8f3aacc2013-01-29 04:21:28 +00003371 bool isDeclSpec, unsigned SpellingListIndex) {
Sean Huntcf807c42010-08-18 23:23:40 +00003372 // FIXME: Cache the number on the Attr object if non-dependent?
3373 // FIXME: Perform checking of type validity
Aaron Ballmanfc685ac2012-06-19 22:09:27 +00003374 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS,
Richard Smith8f3aacc2013-01-29 04:21:28 +00003375 isDeclSpec, SpellingListIndex));
Sean Huntcf807c42010-08-18 23:23:40 +00003376 return;
Chris Lattner6b6b5372008-06-26 18:38:35 +00003377}
Chris Lattnerfbf13472008-06-27 22:18:37 +00003378
Chandler Carruthd309c812011-07-01 23:49:16 +00003379/// handleModeAttr - This attribute modifies the width of a decl with primitive
Mike Stumpbf916502009-07-24 19:02:52 +00003380/// type.
Chris Lattnerfbf13472008-06-27 22:18:37 +00003381///
Mike Stumpbf916502009-07-24 19:02:52 +00003382/// Despite what would be logical, the mode attribute is a decl attribute, not a
3383/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
3384/// HImode, not an intermediate pointer.
Chandler Carruth1b03c872011-07-02 00:01:44 +00003385static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattnerfbf13472008-06-27 22:18:37 +00003386 // This attribute isn't documented, but glibc uses it. It changes
3387 // the width of an int or unsigned int to the specified size.
3388
3389 // Check that there aren't any arguments
Chandler Carruth1731e202011-07-11 23:30:35 +00003390 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattnerfbf13472008-06-27 22:18:37 +00003391 return;
Chandler Carruth1731e202011-07-11 23:30:35 +00003392
Chris Lattnerfbf13472008-06-27 22:18:37 +00003393
3394 IdentifierInfo *Name = Attr.getParameterName();
3395 if (!Name) {
Chris Lattner0b2f4da2008-06-29 00:28:59 +00003396 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
Chris Lattnerfbf13472008-06-27 22:18:37 +00003397 return;
3398 }
Daniel Dunbar210ae982009-10-18 02:09:24 +00003399
Chris Lattner5f9e2722011-07-23 10:55:15 +00003400 StringRef Str = Attr.getParameterName()->getName();
Chris Lattnerfbf13472008-06-27 22:18:37 +00003401
3402 // Normalize the attribute name, __foo__ becomes foo.
Daniel Dunbar210ae982009-10-18 02:09:24 +00003403 if (Str.startswith("__") && Str.endswith("__"))
3404 Str = Str.substr(2, Str.size() - 4);
Chris Lattnerfbf13472008-06-27 22:18:37 +00003405
3406 unsigned DestWidth = 0;
3407 bool IntegerMode = true;
Eli Friedman73397492009-03-03 06:41:03 +00003408 bool ComplexMode = false;
Daniel Dunbar210ae982009-10-18 02:09:24 +00003409 switch (Str.size()) {
Chris Lattnerfbf13472008-06-27 22:18:37 +00003410 case 2:
Eli Friedman73397492009-03-03 06:41:03 +00003411 switch (Str[0]) {
3412 case 'Q': DestWidth = 8; break;
3413 case 'H': DestWidth = 16; break;
3414 case 'S': DestWidth = 32; break;
3415 case 'D': DestWidth = 64; break;
3416 case 'X': DestWidth = 96; break;
3417 case 'T': DestWidth = 128; break;
3418 }
3419 if (Str[1] == 'F') {
3420 IntegerMode = false;
3421 } else if (Str[1] == 'C') {
3422 IntegerMode = false;
3423 ComplexMode = true;
3424 } else if (Str[1] != 'I') {
3425 DestWidth = 0;
3426 }
Chris Lattnerfbf13472008-06-27 22:18:37 +00003427 break;
3428 case 4:
3429 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
3430 // pointer on PIC16 and other embedded platforms.
Daniel Dunbar210ae982009-10-18 02:09:24 +00003431 if (Str == "word")
Douglas Gregorbcfd1f52011-09-02 00:18:52 +00003432 DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
Daniel Dunbar210ae982009-10-18 02:09:24 +00003433 else if (Str == "byte")
Douglas Gregorbcfd1f52011-09-02 00:18:52 +00003434 DestWidth = S.Context.getTargetInfo().getCharWidth();
Chris Lattnerfbf13472008-06-27 22:18:37 +00003435 break;
3436 case 7:
Daniel Dunbar210ae982009-10-18 02:09:24 +00003437 if (Str == "pointer")
Douglas Gregorbcfd1f52011-09-02 00:18:52 +00003438 DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
Chris Lattnerfbf13472008-06-27 22:18:37 +00003439 break;
Rafael Espindola8e721b72013-01-07 19:58:54 +00003440 case 11:
3441 if (Str == "unwind_word")
Rafael Espindola0b1de542013-01-07 20:01:57 +00003442 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
Rafael Espindola8e721b72013-01-07 19:58:54 +00003443 break;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003444 }
3445
3446 QualType OldTy;
Richard Smith162e1c12011-04-15 14:24:37 +00003447 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
Chris Lattnerfbf13472008-06-27 22:18:37 +00003448 OldTy = TD->getUnderlyingType();
3449 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
3450 OldTy = VD->getType();
3451 else {
Chris Lattnerfa25bbb2008-11-19 05:08:23 +00003452 S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
Argyrios Kyrtzidis768d6ca2011-09-13 16:05:58 +00003453 << "mode" << Attr.getRange();
Chris Lattnerfbf13472008-06-27 22:18:37 +00003454 return;
3455 }
Eli Friedman73397492009-03-03 06:41:03 +00003456
John McCall183700f2009-09-21 23:43:11 +00003457 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
Eli Friedman73397492009-03-03 06:41:03 +00003458 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
3459 else if (IntegerMode) {
Douglas Gregor2ade35e2010-06-16 00:17:44 +00003460 if (!OldTy->isIntegralOrEnumerationType())
Eli Friedman73397492009-03-03 06:41:03 +00003461 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3462 } else if (ComplexMode) {
3463 if (!OldTy->isComplexType())
3464 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3465 } else {
3466 if (!OldTy->isFloatingType())
3467 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3468 }
3469
Mike Stump390b4cc2009-05-16 07:39:55 +00003470 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
3471 // and friends, at least with glibc.
3472 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
3473 // width on unusual platforms.
Eli Friedmanf98aba32009-02-13 02:31:07 +00003474 // FIXME: Make sure floating-point mappings are accurate
3475 // FIXME: Support XF and TF types
Chris Lattnerfbf13472008-06-27 22:18:37 +00003476 QualType NewTy;
3477 switch (DestWidth) {
3478 case 0:
Chris Lattner3c73c412008-11-19 08:23:25 +00003479 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003480 return;
3481 default:
Chris Lattner3c73c412008-11-19 08:23:25 +00003482 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003483 return;
3484 case 8:
Eli Friedman73397492009-03-03 06:41:03 +00003485 if (!IntegerMode) {
3486 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3487 return;
3488 }
Chris Lattnerfbf13472008-06-27 22:18:37 +00003489 if (OldTy->isSignedIntegerType())
Chris Lattner0b2f4da2008-06-29 00:28:59 +00003490 NewTy = S.Context.SignedCharTy;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003491 else
Chris Lattner0b2f4da2008-06-29 00:28:59 +00003492 NewTy = S.Context.UnsignedCharTy;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003493 break;
3494 case 16:
Eli Friedman73397492009-03-03 06:41:03 +00003495 if (!IntegerMode) {
3496 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3497 return;
3498 }
Chris Lattnerfbf13472008-06-27 22:18:37 +00003499 if (OldTy->isSignedIntegerType())
Chris Lattner0b2f4da2008-06-29 00:28:59 +00003500 NewTy = S.Context.ShortTy;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003501 else
Chris Lattner0b2f4da2008-06-29 00:28:59 +00003502 NewTy = S.Context.UnsignedShortTy;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003503 break;
3504 case 32:
3505 if (!IntegerMode)
Chris Lattner0b2f4da2008-06-29 00:28:59 +00003506 NewTy = S.Context.FloatTy;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003507 else if (OldTy->isSignedIntegerType())
Chris Lattner0b2f4da2008-06-29 00:28:59 +00003508 NewTy = S.Context.IntTy;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003509 else
Chris Lattner0b2f4da2008-06-29 00:28:59 +00003510 NewTy = S.Context.UnsignedIntTy;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003511 break;
3512 case 64:
3513 if (!IntegerMode)
Chris Lattner0b2f4da2008-06-29 00:28:59 +00003514 NewTy = S.Context.DoubleTy;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003515 else if (OldTy->isSignedIntegerType())
Douglas Gregorbcfd1f52011-09-02 00:18:52 +00003516 if (S.Context.getTargetInfo().getLongWidth() == 64)
Chandler Carruthaec7caa2010-01-26 06:39:24 +00003517 NewTy = S.Context.LongTy;
3518 else
3519 NewTy = S.Context.LongLongTy;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003520 else
Douglas Gregorbcfd1f52011-09-02 00:18:52 +00003521 if (S.Context.getTargetInfo().getLongWidth() == 64)
Chandler Carruthaec7caa2010-01-26 06:39:24 +00003522 NewTy = S.Context.UnsignedLongTy;
3523 else
3524 NewTy = S.Context.UnsignedLongLongTy;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003525 break;
Eli Friedman73397492009-03-03 06:41:03 +00003526 case 96:
3527 NewTy = S.Context.LongDoubleTy;
3528 break;
Eli Friedmanf98aba32009-02-13 02:31:07 +00003529 case 128:
3530 if (!IntegerMode) {
3531 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3532 return;
3533 }
Anders Carlssonf5f7d862009-12-29 07:07:36 +00003534 if (OldTy->isSignedIntegerType())
3535 NewTy = S.Context.Int128Ty;
3536 else
3537 NewTy = S.Context.UnsignedInt128Ty;
Eli Friedman73397492009-03-03 06:41:03 +00003538 break;
Chris Lattnerfbf13472008-06-27 22:18:37 +00003539 }
3540
Eli Friedman73397492009-03-03 06:41:03 +00003541 if (ComplexMode) {
3542 NewTy = S.Context.getComplexType(NewTy);
Chris Lattnerfbf13472008-06-27 22:18:37 +00003543 }
3544
3545 // Install the new type.
Richard Smith162e1c12011-04-15 14:24:37 +00003546 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
John McCallba6a9bd2009-10-24 08:00:42 +00003547 // FIXME: preserve existing source info.
John McCalla93c9342009-12-07 02:54:59 +00003548 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
John McCallba6a9bd2009-10-24 08:00:42 +00003549 } else
Chris Lattnerfbf13472008-06-27 22:18:37 +00003550 cast<ValueDecl>(D)->setType(NewTy);
3551}
Chris Lattner0744e5f2008-06-29 00:23:49 +00003552
Chandler Carruth1b03c872011-07-02 00:01:44 +00003553static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Anders Carlssond87df372009-02-13 06:46:13 +00003554 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00003555 if (!checkAttributeNumArgs(S, Attr, 0))
Anders Carlssond87df372009-02-13 06:46:13 +00003556 return;
Anders Carlssone896d982009-02-13 08:11:52 +00003557
Nick Lewycky78d1a102012-07-24 01:40:49 +00003558 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
3559 if (!VD->hasGlobalStorage())
3560 S.Diag(Attr.getLoc(),
3561 diag::warn_attribute_requires_functions_or_static_globals)
3562 << Attr.getName();
3563 } else if (!isFunctionOrMethod(D)) {
3564 S.Diag(Attr.getLoc(),
3565 diag::warn_attribute_requires_functions_or_static_globals)
3566 << Attr.getName();
Anders Carlssond87df372009-02-13 06:46:13 +00003567 return;
3568 }
Mike Stumpbf916502009-07-24 19:02:52 +00003569
Michael Han51d8c522013-01-24 16:46:58 +00003570 D->addAttr(::new (S.Context)
3571 NoDebugAttr(Attr.getRange(), S.Context,
3572 Attr.getAttributeSpellingListIndex()));
Anders Carlssond87df372009-02-13 06:46:13 +00003573}
3574
Chandler Carruth1b03c872011-07-02 00:01:44 +00003575static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Anders Carlsson5bab7882009-02-19 19:16:48 +00003576 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00003577 if (!checkAttributeNumArgs(S, Attr, 0))
Anders Carlsson5bab7882009-02-19 19:16:48 +00003578 return;
Chandler Carruth1731e202011-07-11 23:30:35 +00003579
Mike Stumpbf916502009-07-24 19:02:52 +00003580
Chandler Carruth87c44602011-07-01 23:49:12 +00003581 if (!isa<FunctionDecl>(D)) {
Anders Carlsson5bab7882009-02-19 19:16:48 +00003582 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00003583 << Attr.getName() << ExpectedFunction;
Anders Carlsson5bab7882009-02-19 19:16:48 +00003584 return;
3585 }
Mike Stumpbf916502009-07-24 19:02:52 +00003586
Michael Han51d8c522013-01-24 16:46:58 +00003587 D->addAttr(::new (S.Context)
3588 NoInlineAttr(Attr.getRange(), S.Context,
3589 Attr.getAttributeSpellingListIndex()));
Anders Carlsson5bab7882009-02-19 19:16:48 +00003590}
3591
Chandler Carruth1b03c872011-07-02 00:01:44 +00003592static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
3593 const AttributeList &Attr) {
Chris Lattner7255a2d2010-06-22 00:03:40 +00003594 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00003595 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattner7255a2d2010-06-22 00:03:40 +00003596 return;
Chandler Carruth1731e202011-07-11 23:30:35 +00003597
Chris Lattner7255a2d2010-06-22 00:03:40 +00003598
Chandler Carruth87c44602011-07-01 23:49:12 +00003599 if (!isa<FunctionDecl>(D)) {
Chris Lattner7255a2d2010-06-22 00:03:40 +00003600 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00003601 << Attr.getName() << ExpectedFunction;
Chris Lattner7255a2d2010-06-22 00:03:40 +00003602 return;
3603 }
3604
Michael Han51d8c522013-01-24 16:46:58 +00003605 D->addAttr(::new (S.Context)
3606 NoInstrumentFunctionAttr(Attr.getRange(), S.Context,
3607 Attr.getAttributeSpellingListIndex()));
Chris Lattner7255a2d2010-06-22 00:03:40 +00003608}
3609
Chandler Carruth1b03c872011-07-02 00:01:44 +00003610static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Peter Collingbourneced76712010-12-01 03:15:31 +00003611 if (S.LangOpts.CUDA) {
3612 // check the attribute arguments.
Ted Kremenek831efae2011-04-15 05:49:29 +00003613 if (Attr.hasParameterOrArguments()) {
Peter Collingbourneced76712010-12-01 03:15:31 +00003614 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3615 return;
3616 }
3617
Chandler Carruth87c44602011-07-01 23:49:12 +00003618 if (!isa<VarDecl>(D)) {
Peter Collingbourneced76712010-12-01 03:15:31 +00003619 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00003620 << Attr.getName() << ExpectedVariable;
Peter Collingbourneced76712010-12-01 03:15:31 +00003621 return;
3622 }
3623
Michael Han51d8c522013-01-24 16:46:58 +00003624 D->addAttr(::new (S.Context)
3625 CUDAConstantAttr(Attr.getRange(), S.Context,
3626 Attr.getAttributeSpellingListIndex()));
Peter Collingbourneced76712010-12-01 03:15:31 +00003627 } else {
3628 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
3629 }
3630}
3631
Chandler Carruth1b03c872011-07-02 00:01:44 +00003632static void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Peter Collingbourneced76712010-12-01 03:15:31 +00003633 if (S.LangOpts.CUDA) {
3634 // check the attribute arguments.
3635 if (Attr.getNumArgs() != 0) {
3636 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
3637 return;
3638 }
3639
Chandler Carruth87c44602011-07-01 23:49:12 +00003640 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
Peter Collingbourneced76712010-12-01 03:15:31 +00003641 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00003642 << Attr.getName() << ExpectedVariableOrFunction;
Peter Collingbourneced76712010-12-01 03:15:31 +00003643 return;
3644 }
3645
Michael Han51d8c522013-01-24 16:46:58 +00003646 D->addAttr(::new (S.Context)
3647 CUDADeviceAttr(Attr.getRange(), S.Context,
3648 Attr.getAttributeSpellingListIndex()));
Peter Collingbourneced76712010-12-01 03:15:31 +00003649 } else {
3650 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
3651 }
3652}
3653
Chandler Carruth1b03c872011-07-02 00:01:44 +00003654static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Peter Collingbourneced76712010-12-01 03:15:31 +00003655 if (S.LangOpts.CUDA) {
3656 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00003657 if (!checkAttributeNumArgs(S, Attr, 0))
Peter Collingbourneced76712010-12-01 03:15:31 +00003658 return;
Peter Collingbourneced76712010-12-01 03:15:31 +00003659
Chandler Carruth87c44602011-07-01 23:49:12 +00003660 if (!isa<FunctionDecl>(D)) {
Peter Collingbourneced76712010-12-01 03:15:31 +00003661 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00003662 << Attr.getName() << ExpectedFunction;
Peter Collingbourneced76712010-12-01 03:15:31 +00003663 return;
3664 }
3665
Chandler Carruth87c44602011-07-01 23:49:12 +00003666 FunctionDecl *FD = cast<FunctionDecl>(D);
Peter Collingbourne2c2c8dd2010-12-12 23:02:57 +00003667 if (!FD->getResultType()->isVoidType()) {
Abramo Bagnara723df242010-12-14 22:11:44 +00003668 TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
Peter Collingbourne2c2c8dd2010-12-12 23:02:57 +00003669 if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
3670 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
3671 << FD->getType()
3672 << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
3673 "void");
3674 } else {
3675 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
3676 << FD->getType();
3677 }
3678 return;
3679 }
3680
Michael Han51d8c522013-01-24 16:46:58 +00003681 D->addAttr(::new (S.Context)
3682 CUDAGlobalAttr(Attr.getRange(), S.Context,
3683 Attr.getAttributeSpellingListIndex()));
Peter Collingbourneced76712010-12-01 03:15:31 +00003684 } else {
3685 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
3686 }
3687}
3688
Chandler Carruth1b03c872011-07-02 00:01:44 +00003689static void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Peter Collingbourneced76712010-12-01 03:15:31 +00003690 if (S.LangOpts.CUDA) {
3691 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00003692 if (!checkAttributeNumArgs(S, Attr, 0))
Peter Collingbourneced76712010-12-01 03:15:31 +00003693 return;
Chandler Carruth1731e202011-07-11 23:30:35 +00003694
Peter Collingbourneced76712010-12-01 03:15:31 +00003695
Chandler Carruth87c44602011-07-01 23:49:12 +00003696 if (!isa<FunctionDecl>(D)) {
Peter Collingbourneced76712010-12-01 03:15:31 +00003697 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00003698 << Attr.getName() << ExpectedFunction;
Peter Collingbourneced76712010-12-01 03:15:31 +00003699 return;
3700 }
3701
Michael Han51d8c522013-01-24 16:46:58 +00003702 D->addAttr(::new (S.Context)
3703 CUDAHostAttr(Attr.getRange(), S.Context,
3704 Attr.getAttributeSpellingListIndex()));
Peter Collingbourneced76712010-12-01 03:15:31 +00003705 } else {
3706 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
3707 }
3708}
3709
Chandler Carruth1b03c872011-07-02 00:01:44 +00003710static void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Peter Collingbourneced76712010-12-01 03:15:31 +00003711 if (S.LangOpts.CUDA) {
3712 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00003713 if (!checkAttributeNumArgs(S, Attr, 0))
Peter Collingbourneced76712010-12-01 03:15:31 +00003714 return;
Chandler Carruth1731e202011-07-11 23:30:35 +00003715
Chandler Carruth87c44602011-07-01 23:49:12 +00003716 if (!isa<VarDecl>(D)) {
Peter Collingbourneced76712010-12-01 03:15:31 +00003717 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00003718 << Attr.getName() << ExpectedVariable;
Peter Collingbourneced76712010-12-01 03:15:31 +00003719 return;
3720 }
3721
Michael Han51d8c522013-01-24 16:46:58 +00003722 D->addAttr(::new (S.Context)
3723 CUDASharedAttr(Attr.getRange(), S.Context,
3724 Attr.getAttributeSpellingListIndex()));
Peter Collingbourneced76712010-12-01 03:15:31 +00003725 } else {
3726 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
3727 }
3728}
3729
Chandler Carruth1b03c872011-07-02 00:01:44 +00003730static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chris Lattner26e25542009-04-14 16:30:50 +00003731 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00003732 if (!checkAttributeNumArgs(S, Attr, 0))
Chris Lattner26e25542009-04-14 16:30:50 +00003733 return;
Mike Stumpbf916502009-07-24 19:02:52 +00003734
Chandler Carruth87c44602011-07-01 23:49:12 +00003735 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
Chris Lattnerc5197432009-04-14 17:02:11 +00003736 if (Fn == 0) {
Chris Lattner26e25542009-04-14 16:30:50 +00003737 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00003738 << Attr.getName() << ExpectedFunction;
Chris Lattner26e25542009-04-14 16:30:50 +00003739 return;
3740 }
Mike Stumpbf916502009-07-24 19:02:52 +00003741
Douglas Gregor0130f3c2009-10-27 21:01:01 +00003742 if (!Fn->isInlineSpecified()) {
Chris Lattnercf2a7212009-04-20 19:12:28 +00003743 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
Chris Lattnerc5197432009-04-14 17:02:11 +00003744 return;
3745 }
Mike Stumpbf916502009-07-24 19:02:52 +00003746
Michael Han51d8c522013-01-24 16:46:58 +00003747 D->addAttr(::new (S.Context)
3748 GNUInlineAttr(Attr.getRange(), S.Context,
3749 Attr.getAttributeSpellingListIndex()));
Chris Lattner26e25542009-04-14 16:30:50 +00003750}
3751
Chandler Carruth1b03c872011-07-02 00:01:44 +00003752static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruth87c44602011-07-01 23:49:12 +00003753 if (hasDeclarator(D)) return;
Abramo Bagnarae215f722010-04-30 13:10:51 +00003754
Aaron Ballmanfff32482012-12-09 17:45:41 +00003755 const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
Chandler Carruth87c44602011-07-01 23:49:12 +00003756 // Diagnostic is emitted elsewhere: here we store the (valid) Attr
John McCall711c52b2011-01-05 12:14:39 +00003757 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
3758 CallingConv CC;
Aaron Ballmanfff32482012-12-09 17:45:41 +00003759 if (S.CheckCallingConvAttr(Attr, CC, FD))
John McCall711c52b2011-01-05 12:14:39 +00003760 return;
3761
Chandler Carruth87c44602011-07-01 23:49:12 +00003762 if (!isa<ObjCMethodDecl>(D)) {
3763 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3764 << Attr.getName() << ExpectedFunctionOrMethod;
John McCall711c52b2011-01-05 12:14:39 +00003765 return;
3766 }
3767
Chandler Carruth87c44602011-07-01 23:49:12 +00003768 switch (Attr.getKind()) {
Sean Hunt8e083e72012-06-19 23:57:03 +00003769 case AttributeList::AT_FastCall:
Michael Han51d8c522013-01-24 16:46:58 +00003770 D->addAttr(::new (S.Context)
3771 FastCallAttr(Attr.getRange(), S.Context,
3772 Attr.getAttributeSpellingListIndex()));
Abramo Bagnarae215f722010-04-30 13:10:51 +00003773 return;
Sean Hunt8e083e72012-06-19 23:57:03 +00003774 case AttributeList::AT_StdCall:
Michael Han51d8c522013-01-24 16:46:58 +00003775 D->addAttr(::new (S.Context)
3776 StdCallAttr(Attr.getRange(), S.Context,
3777 Attr.getAttributeSpellingListIndex()));
Abramo Bagnarae215f722010-04-30 13:10:51 +00003778 return;
Sean Hunt8e083e72012-06-19 23:57:03 +00003779 case AttributeList::AT_ThisCall:
Michael Han51d8c522013-01-24 16:46:58 +00003780 D->addAttr(::new (S.Context)
3781 ThisCallAttr(Attr.getRange(), S.Context,
3782 Attr.getAttributeSpellingListIndex()));
Douglas Gregor04633eb2010-08-30 23:30:49 +00003783 return;
Sean Hunt8e083e72012-06-19 23:57:03 +00003784 case AttributeList::AT_CDecl:
Michael Han51d8c522013-01-24 16:46:58 +00003785 D->addAttr(::new (S.Context)
3786 CDeclAttr(Attr.getRange(), S.Context,
3787 Attr.getAttributeSpellingListIndex()));
Abramo Bagnarae215f722010-04-30 13:10:51 +00003788 return;
Sean Hunt8e083e72012-06-19 23:57:03 +00003789 case AttributeList::AT_Pascal:
Michael Han51d8c522013-01-24 16:46:58 +00003790 D->addAttr(::new (S.Context)
3791 PascalAttr(Attr.getRange(), S.Context,
3792 Attr.getAttributeSpellingListIndex()));
Dawn Perchik52fc3142010-09-03 01:29:35 +00003793 return;
Sean Hunt8e083e72012-06-19 23:57:03 +00003794 case AttributeList::AT_Pcs: {
Anton Korobeynikov414d8962011-04-14 20:06:49 +00003795 PcsAttr::PCSType PCS;
Benjamin Kramer9071def2012-08-14 13:24:39 +00003796 switch (CC) {
3797 case CC_AAPCS:
Anton Korobeynikov414d8962011-04-14 20:06:49 +00003798 PCS = PcsAttr::AAPCS;
Benjamin Kramer9071def2012-08-14 13:24:39 +00003799 break;
3800 case CC_AAPCS_VFP:
Anton Korobeynikov414d8962011-04-14 20:06:49 +00003801 PCS = PcsAttr::AAPCS_VFP;
Benjamin Kramer9071def2012-08-14 13:24:39 +00003802 break;
3803 default:
3804 llvm_unreachable("unexpected calling convention in pcs attribute");
Anton Korobeynikov414d8962011-04-14 20:06:49 +00003805 }
3806
Michael Han51d8c522013-01-24 16:46:58 +00003807 D->addAttr(::new (S.Context)
3808 PcsAttr(Attr.getRange(), S.Context, PCS,
3809 Attr.getAttributeSpellingListIndex()));
Derek Schuff263366f2012-10-16 22:30:41 +00003810 return;
Anton Korobeynikov414d8962011-04-14 20:06:49 +00003811 }
Derek Schuff263366f2012-10-16 22:30:41 +00003812 case AttributeList::AT_PnaclCall:
Michael Han51d8c522013-01-24 16:46:58 +00003813 D->addAttr(::new (S.Context)
3814 PnaclCallAttr(Attr.getRange(), S.Context,
3815 Attr.getAttributeSpellingListIndex()));
Derek Schuff263366f2012-10-16 22:30:41 +00003816 return;
Guy Benyei38980082012-12-25 08:53:55 +00003817 case AttributeList::AT_IntelOclBicc:
Michael Han51d8c522013-01-24 16:46:58 +00003818 D->addAttr(::new (S.Context)
3819 IntelOclBiccAttr(Attr.getRange(), S.Context,
3820 Attr.getAttributeSpellingListIndex()));
Guy Benyei38980082012-12-25 08:53:55 +00003821 return;
Derek Schuff263366f2012-10-16 22:30:41 +00003822
Abramo Bagnarae215f722010-04-30 13:10:51 +00003823 default:
3824 llvm_unreachable("unexpected attribute kind");
Abramo Bagnarae215f722010-04-30 13:10:51 +00003825 }
3826}
3827
Chandler Carruth1b03c872011-07-02 00:01:44 +00003828static void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
Chandler Carruth56aeb402011-07-11 23:33:05 +00003829 assert(!Attr.isInvalid());
Argyrios Kyrtzidis768d6ca2011-09-13 16:05:58 +00003830 D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
Peter Collingbournef315fa82011-02-14 01:42:53 +00003831}
3832
Aaron Ballmanfff32482012-12-09 17:45:41 +00003833bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
3834 const FunctionDecl *FD) {
John McCall711c52b2011-01-05 12:14:39 +00003835 if (attr.isInvalid())
3836 return true;
3837
Benjamin Kramerfac8e432012-08-14 13:13:47 +00003838 unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0;
3839 if (attr.getNumArgs() != ReqArgs || attr.getParameterName()) {
3840 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << ReqArgs;
John McCall711c52b2011-01-05 12:14:39 +00003841 attr.setInvalid();
3842 return true;
3843 }
3844
Anton Korobeynikov414d8962011-04-14 20:06:49 +00003845 // TODO: diagnose uses of these conventions on the wrong target. Or, better
3846 // move to TargetAttributesSema one day.
John McCall711c52b2011-01-05 12:14:39 +00003847 switch (attr.getKind()) {
Sean Hunt8e083e72012-06-19 23:57:03 +00003848 case AttributeList::AT_CDecl: CC = CC_C; break;
3849 case AttributeList::AT_FastCall: CC = CC_X86FastCall; break;
3850 case AttributeList::AT_StdCall: CC = CC_X86StdCall; break;
3851 case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break;
3852 case AttributeList::AT_Pascal: CC = CC_X86Pascal; break;
3853 case AttributeList::AT_Pcs: {
Anton Korobeynikov414d8962011-04-14 20:06:49 +00003854 Expr *Arg = attr.getArg(0);
3855 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
Douglas Gregor5cee1192011-07-27 05:40:30 +00003856 if (!Str || !Str->isAscii()) {
Anton Korobeynikov414d8962011-04-14 20:06:49 +00003857 Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
3858 << "pcs" << 1;
3859 attr.setInvalid();
3860 return true;
3861 }
3862
Chris Lattner5f9e2722011-07-23 10:55:15 +00003863 StringRef StrRef = Str->getString();
Anton Korobeynikov414d8962011-04-14 20:06:49 +00003864 if (StrRef == "aapcs") {
3865 CC = CC_AAPCS;
3866 break;
3867 } else if (StrRef == "aapcs-vfp") {
3868 CC = CC_AAPCS_VFP;
3869 break;
3870 }
Benjamin Kramerfac8e432012-08-14 13:13:47 +00003871
3872 attr.setInvalid();
3873 Diag(attr.getLoc(), diag::err_invalid_pcs);
3874 return true;
Anton Korobeynikov414d8962011-04-14 20:06:49 +00003875 }
Derek Schuff263366f2012-10-16 22:30:41 +00003876 case AttributeList::AT_PnaclCall: CC = CC_PnaclCall; break;
Guy Benyei38980082012-12-25 08:53:55 +00003877 case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break;
David Blaikie7530c032012-01-17 06:56:22 +00003878 default: llvm_unreachable("unexpected attribute kind");
John McCall711c52b2011-01-05 12:14:39 +00003879 }
3880
Aaron Ballman82bfa192012-10-02 14:26:08 +00003881 const TargetInfo &TI = Context.getTargetInfo();
3882 TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC);
3883 if (A == TargetInfo::CCCR_Warning) {
3884 Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName();
Aaron Ballmanfff32482012-12-09 17:45:41 +00003885
3886 TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown;
3887 if (FD)
3888 MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member :
3889 TargetInfo::CCMT_NonMember;
3890 CC = TI.getDefaultCallingConv(MT);
Aaron Ballman82bfa192012-10-02 14:26:08 +00003891 }
3892
John McCall711c52b2011-01-05 12:14:39 +00003893 return false;
3894}
3895
Chandler Carruth1b03c872011-07-02 00:01:44 +00003896static void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruth87c44602011-07-01 23:49:12 +00003897 if (hasDeclarator(D)) return;
John McCall711c52b2011-01-05 12:14:39 +00003898
3899 unsigned numParams;
Chandler Carruth87c44602011-07-01 23:49:12 +00003900 if (S.CheckRegparmAttr(Attr, numParams))
John McCall711c52b2011-01-05 12:14:39 +00003901 return;
3902
Chandler Carruth87c44602011-07-01 23:49:12 +00003903 if (!isa<ObjCMethodDecl>(D)) {
3904 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3905 << Attr.getName() << ExpectedFunctionOrMethod;
Fariborz Jahanianee760332009-03-27 18:38:55 +00003906 return;
3907 }
Eli Friedman55d3aaf2009-03-27 21:06:47 +00003908
Michael Han51d8c522013-01-24 16:46:58 +00003909 D->addAttr(::new (S.Context)
3910 RegparmAttr(Attr.getRange(), S.Context, numParams,
3911 Attr.getAttributeSpellingListIndex()));
John McCall711c52b2011-01-05 12:14:39 +00003912}
3913
3914/// Checks a regparm attribute, returning true if it is ill-formed and
3915/// otherwise setting numParams to the appropriate value.
Chandler Carruth87c44602011-07-01 23:49:12 +00003916bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
3917 if (Attr.isInvalid())
John McCall711c52b2011-01-05 12:14:39 +00003918 return true;
3919
Chandler Carruth87c44602011-07-01 23:49:12 +00003920 if (Attr.getNumArgs() != 1) {
3921 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
3922 Attr.setInvalid();
John McCall711c52b2011-01-05 12:14:39 +00003923 return true;
Fariborz Jahanianee760332009-03-27 18:38:55 +00003924 }
Eli Friedman55d3aaf2009-03-27 21:06:47 +00003925
Chandler Carruth87c44602011-07-01 23:49:12 +00003926 Expr *NumParamsExpr = Attr.getArg(0);
Eli Friedman55d3aaf2009-03-27 21:06:47 +00003927 llvm::APSInt NumParams(32);
Douglas Gregorac06a0e2010-05-18 23:01:22 +00003928 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
John McCall711c52b2011-01-05 12:14:39 +00003929 !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
Chandler Carruth87c44602011-07-01 23:49:12 +00003930 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
Eli Friedman55d3aaf2009-03-27 21:06:47 +00003931 << "regparm" << NumParamsExpr->getSourceRange();
Chandler Carruth87c44602011-07-01 23:49:12 +00003932 Attr.setInvalid();
John McCall711c52b2011-01-05 12:14:39 +00003933 return true;
Eli Friedman55d3aaf2009-03-27 21:06:47 +00003934 }
3935
Douglas Gregorbcfd1f52011-09-02 00:18:52 +00003936 if (Context.getTargetInfo().getRegParmMax() == 0) {
Chandler Carruth87c44602011-07-01 23:49:12 +00003937 Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
Eli Friedman55d3aaf2009-03-27 21:06:47 +00003938 << NumParamsExpr->getSourceRange();
Chandler Carruth87c44602011-07-01 23:49:12 +00003939 Attr.setInvalid();
John McCall711c52b2011-01-05 12:14:39 +00003940 return true;
Eli Friedman55d3aaf2009-03-27 21:06:47 +00003941 }
3942
John McCall711c52b2011-01-05 12:14:39 +00003943 numParams = NumParams.getZExtValue();
Douglas Gregorbcfd1f52011-09-02 00:18:52 +00003944 if (numParams > Context.getTargetInfo().getRegParmMax()) {
Chandler Carruth87c44602011-07-01 23:49:12 +00003945 Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
Douglas Gregorbcfd1f52011-09-02 00:18:52 +00003946 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
Chandler Carruth87c44602011-07-01 23:49:12 +00003947 Attr.setInvalid();
John McCall711c52b2011-01-05 12:14:39 +00003948 return true;
Eli Friedman55d3aaf2009-03-27 21:06:47 +00003949 }
3950
John McCall711c52b2011-01-05 12:14:39 +00003951 return false;
Fariborz Jahanianee760332009-03-27 18:38:55 +00003952}
3953
Chandler Carruth1b03c872011-07-02 00:01:44 +00003954static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
Peter Collingbourne7b381982010-12-12 23:03:07 +00003955 if (S.LangOpts.CUDA) {
3956 // check the attribute arguments.
3957 if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
John McCallbdc49d32011-03-02 12:15:05 +00003958 // FIXME: 0 is not okay.
3959 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
Peter Collingbourne7b381982010-12-12 23:03:07 +00003960 return;
3961 }
3962
Chandler Carruth87c44602011-07-01 23:49:12 +00003963 if (!isFunctionOrMethod(D)) {
Peter Collingbourne7b381982010-12-12 23:03:07 +00003964 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
John McCall883cc2c2011-03-02 12:29:23 +00003965 << Attr.getName() << ExpectedFunctionOrMethod;
Peter Collingbourne7b381982010-12-12 23:03:07 +00003966 return;
3967 }
3968
3969 Expr *MaxThreadsExpr = Attr.getArg(0);
3970 llvm::APSInt MaxThreads(32);
3971 if (MaxThreadsExpr->isTypeDependent() ||
3972 MaxThreadsExpr->isValueDependent() ||
3973 !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
3974 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
3975 << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
3976 return;
3977 }
3978
3979 llvm::APSInt MinBlocks(32);
3980 if (Attr.getNumArgs() > 1) {
3981 Expr *MinBlocksExpr = Attr.getArg(1);
3982 if (MinBlocksExpr->isTypeDependent() ||
3983 MinBlocksExpr->isValueDependent() ||
3984 !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
3985 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
3986 << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
3987 return;
3988 }
3989 }
3990
Michael Han51d8c522013-01-24 16:46:58 +00003991 D->addAttr(::new (S.Context)
3992 CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
3993 MaxThreads.getZExtValue(),
3994 MinBlocks.getZExtValue(),
3995 Attr.getAttributeSpellingListIndex()));
Peter Collingbourne7b381982010-12-12 23:03:07 +00003996 } else {
3997 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
3998 }
3999}
4000
Dmitri Gribenko0d5a0692012-08-17 00:08:38 +00004001static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
4002 const AttributeList &Attr) {
4003 StringRef AttrName = Attr.getName()->getName();
4004 if (!Attr.getParameterName()) {
4005 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier)
4006 << Attr.getName() << /* arg num = */ 1;
4007 return;
4008 }
4009
4010 if (Attr.getNumArgs() != 2) {
4011 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
4012 << /* required args = */ 3;
4013 return;
4014 }
4015
4016 IdentifierInfo *ArgumentKind = Attr.getParameterName();
4017
4018 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
4019 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
4020 << Attr.getName() << ExpectedFunctionOrMethod;
4021 return;
4022 }
4023
4024 uint64_t ArgumentIdx;
4025 if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
4026 Attr.getLoc(), 2,
4027 Attr.getArg(0), ArgumentIdx))
4028 return;
4029
4030 uint64_t TypeTagIdx;
4031 if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
4032 Attr.getLoc(), 3,
4033 Attr.getArg(1), TypeTagIdx))
4034 return;
4035
4036 bool IsPointer = (AttrName == "pointer_with_type_tag");
4037 if (IsPointer) {
4038 // Ensure that buffer has a pointer type.
4039 QualType BufferTy = getFunctionOrMethodArgType(D, ArgumentIdx);
4040 if (!BufferTy->isPointerType()) {
4041 S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only)
4042 << AttrName;
4043 }
4044 }
4045
Michael Han51d8c522013-01-24 16:46:58 +00004046 D->addAttr(::new (S.Context)
4047 ArgumentWithTypeTagAttr(Attr.getRange(), S.Context, ArgumentKind,
4048 ArgumentIdx, TypeTagIdx, IsPointer,
4049 Attr.getAttributeSpellingListIndex()));
Dmitri Gribenko0d5a0692012-08-17 00:08:38 +00004050}
4051
4052static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
4053 const AttributeList &Attr) {
4054 IdentifierInfo *PointerKind = Attr.getParameterName();
4055 if (!PointerKind) {
4056 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier)
4057 << "type_tag_for_datatype" << 1;
4058 return;
4059 }
4060
4061 QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL);
4062
Michael Han51d8c522013-01-24 16:46:58 +00004063 D->addAttr(::new (S.Context)
4064 TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind,
4065 MatchingCType,
4066 Attr.getLayoutCompatible(),
4067 Attr.getMustBeNull(),
4068 Attr.getAttributeSpellingListIndex()));
Dmitri Gribenko0d5a0692012-08-17 00:08:38 +00004069}
4070
Chris Lattner0744e5f2008-06-29 00:23:49 +00004071//===----------------------------------------------------------------------===//
Ted Kremenekb71368d2009-05-09 02:44:38 +00004072// Checker-specific attribute handlers.
4073//===----------------------------------------------------------------------===//
4074
John McCallc7ad3812011-01-25 03:31:58 +00004075static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
Douglas Gregor6c73a292011-10-09 22:26:49 +00004076 return type->isDependentType() ||
4077 type->isObjCObjectPointerType() ||
4078 S.Context.isObjCNSObjectType(type);
John McCallc7ad3812011-01-25 03:31:58 +00004079}
4080static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
Douglas Gregor6c73a292011-10-09 22:26:49 +00004081 return type->isDependentType() ||
4082 type->isPointerType() ||
4083 isValidSubjectOfNSAttribute(S, type);
John McCallc7ad3812011-01-25 03:31:58 +00004084}
4085
Chandler Carruth1b03c872011-07-02 00:01:44 +00004086static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Chandler Carruth87c44602011-07-01 23:49:12 +00004087 ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
John McCallc7ad3812011-01-25 03:31:58 +00004088 if (!param) {
Chandler Carruth87c44602011-07-01 23:49:12 +00004089 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
Argyrios Kyrtzidis768d6ca2011-09-13 16:05:58 +00004090 << Attr.getRange() << Attr.getName() << ExpectedParameter;
John McCallc7ad3812011-01-25 03:31:58 +00004091 return;
4092 }
4093
4094 bool typeOK, cf;
Sean Hunt8e083e72012-06-19 23:57:03 +00004095 if (Attr.getKind() == AttributeList::AT_NSConsumed) {
John McCallc7ad3812011-01-25 03:31:58 +00004096 typeOK = isValidSubjectOfNSAttribute(S, param->getType());
4097 cf = false;
4098 } else {
4099 typeOK = isValidSubjectOfCFAttribute(S, param->getType());
4100 cf = true;
4101 }
4102
4103 if (!typeOK) {
Chandler Carruth87c44602011-07-01 23:49:12 +00004104 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
Argyrios Kyrtzidis768d6ca2011-09-13 16:05:58 +00004105 << Attr.getRange() << Attr.getName() << cf;
John McCallc7ad3812011-01-25 03:31:58 +00004106 return;
4107 }
4108
4109 if (cf)
Michael Han51d8c522013-01-24 16:46:58 +00004110 param->addAttr(::new (S.Context)
4111 CFConsumedAttr(Attr.getRange(), S.Context,
4112 Attr.getAttributeSpellingListIndex()));
John McCallc7ad3812011-01-25 03:31:58 +00004113 else
Michael Han51d8c522013-01-24 16:46:58 +00004114 param->addAttr(::new (S.Context)
4115 NSConsumedAttr(Attr.getRange(), S.Context,
4116 Attr.getAttributeSpellingListIndex()));
John McCallc7ad3812011-01-25 03:31:58 +00004117}
4118
Chandler Carruth1b03c872011-07-02 00:01:44 +00004119static void handleNSConsumesSelfAttr(Sema &S, Decl *D,
4120 const AttributeList &Attr) {
Chandler Carruth87c44602011-07-01 23:49:12 +00004121 if (!isa<ObjCMethodDecl>(D)) {
4122 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
Argyrios Kyrtzidis768d6ca2011-09-13 16:05:58 +00004123 << Attr.getRange() << Attr.getName() << ExpectedMethod;
John McCallc7ad3812011-01-25 03:31:58 +00004124 return;
4125 }
4126
Michael Han51d8c522013-01-24 16:46:58 +00004127 D->addAttr(::new (S.Context)
4128 NSConsumesSelfAttr(Attr.getRange(), S.Context,
4129 Attr.getAttributeSpellingListIndex()));
John McCallc7ad3812011-01-25 03:31:58 +00004130}
4131
Chandler Carruth1b03c872011-07-02 00:01:44 +00004132static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
4133 const AttributeList &Attr) {
Ted Kremenekb71368d2009-05-09 02:44:38 +00004134
John McCallc7ad3812011-01-25 03:31:58 +00004135 QualType returnType;
Mike Stumpbf916502009-07-24 19:02:52 +00004136
Chandler Carruth87c44602011-07-01 23:49:12 +00004137 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
John McCallc7ad3812011-01-25 03:31:58 +00004138 returnType = MD->getResultType();
David Blaikie4e4d0842012-03-11 07:00:24 +00004139 else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
Sean Hunt8e083e72012-06-19 23:57:03 +00004140 (Attr.getKind() == AttributeList::AT_NSReturnsRetained))
John McCallf85e1932011-06-15 23:02:42 +00004141 return; // ignore: was handled as a type attribute
Fariborz Jahaniana23bd4c2012-08-28 22:26:21 +00004142 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
4143 returnType = PD->getType();
Chandler Carruth87c44602011-07-01 23:49:12 +00004144 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
John McCallc7ad3812011-01-25 03:31:58 +00004145 returnType = FD->getResultType();
Ted Kremenek5dc53c92009-05-13 21:07:32 +00004146 else {
Chandler Carruth87c44602011-07-01 23:49:12 +00004147 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
Argyrios Kyrtzidis768d6ca2011-09-13 16:05:58 +00004148 << Attr.getRange() << Attr.getName()
John McCall883cc2c2011-03-02 12:29:23 +00004149 << ExpectedFunctionOrMethod;
Ted Kremenekb71368d2009-05-09 02:44:38 +00004150 return;
4151 }
Mike Stumpbf916502009-07-24 19:02:52 +00004152
John McCallc7ad3812011-01-25 03:31:58 +00004153 bool typeOK;
4154 bool cf;
Chandler Carruth87c44602011-07-01 23:49:12 +00004155 switch (Attr.getKind()) {
David Blaikie7530c032012-01-17 06:56:22 +00004156 default: llvm_unreachable("invalid ownership attribute");
Sean Hunt8e083e72012-06-19 23:57:03 +00004157 case AttributeList::AT_NSReturnsAutoreleased:
4158 case AttributeList::AT_NSReturnsRetained:
4159 case AttributeList::AT_NSReturnsNotRetained:
John McCallc7ad3812011-01-25 03:31:58 +00004160 typeOK = isValidSubjectOfNSAttribute(S, returnType);
4161 cf = false;
4162 break;
4163
Sean Hunt8e083e72012-06-19 23:57:03 +00004164 case AttributeList::AT_CFReturnsRetained:
4165 case AttributeList::AT_CFReturnsNotRetained:
John McCallc7ad3812011-01-25 03:31:58 +00004166 typeOK = isValidSubjectOfCFAttribute(S, returnType);
4167 cf = true;
4168 break;
4169 }
4170
4171 if (!typeOK) {
Chandler Carruth87c44602011-07-01 23:49:12 +00004172 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
Argyrios Kyrtzidis768d6ca2011-09-13 16:05:58 +00004173 << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
Mike Stumpbf916502009-07-24 19:02:52 +00004174 return;
Ted Kremenek5dc53c92009-05-13 21:07:32 +00004175 }
Mike Stumpbf916502009-07-24 19:02:52 +00004176
Chandler Carruth87c44602011-07-01 23:49:12 +00004177 switch (Attr.getKind()) {
Ted Kremenekb71368d2009-05-09 02:44:38 +00004178 default:
David Blaikieb219cfc2011-09-23 05:06:16 +00004179 llvm_unreachable("invalid ownership attribute");
Sean Hunt8e083e72012-06-19 23:57:03 +00004180 case AttributeList::AT_NSReturnsAutoreleased:
Michael Han51d8c522013-01-24 16:46:58 +00004181 D->addAttr(::new (S.Context)
4182 NSReturnsAutoreleasedAttr(Attr.getRange(), S.Context,
4183 Attr.getAttributeSpellingListIndex()));
John McCallc7ad3812011-01-25 03:31:58 +00004184 return;
Sean Hunt8e083e72012-06-19 23:57:03 +00004185 case AttributeList::AT_CFReturnsNotRetained:
Michael Han51d8c522013-01-24 16:46:58 +00004186 D->addAttr(::new (S.Context)
4187 CFReturnsNotRetainedAttr(Attr.getRange(), S.Context,
4188 Attr.getAttributeSpellingListIndex()));
Ted Kremenek31c780d2010-02-18 00:05:45 +00004189 return;
Sean Hunt8e083e72012-06-19 23:57:03 +00004190 case AttributeList::AT_NSReturnsNotRetained:
Michael Han51d8c522013-01-24 16:46:58 +00004191 D->addAttr(::new (S.Context)
4192 NSReturnsNotRetainedAttr(Attr.getRange(), S.Context,
4193 Attr.getAttributeSpellingListIndex()));
Ted Kremenek31c780d2010-02-18 00:05:45 +00004194 return;
Sean Hunt8e083e72012-06-19 23:57:03 +00004195 case AttributeList::AT_CFReturnsRetained:
Michael Han51d8c522013-01-24 16:46:58 +00004196 D->addAttr(::new (S.Context)
4197 CFReturnsRetainedAttr(Attr.getRange(), S.Context,
4198 Attr.getAttributeSpellingListIndex()));
Ted Kremenekb71368d2009-05-09 02:44:38 +00004199 return;
Sean Hunt8e083e72012-06-19 23:57:03 +00004200 case AttributeList::AT_NSReturnsRetained:
Michael Han51d8c522013-01-24 16:46:58 +00004201 D->addAttr(::new (S.Context)
4202 NSReturnsRetainedAttr(Attr.getRange(), S.Context,
4203 Attr.getAttributeSpellingListIndex()));
Ted Kremenekb71368d2009-05-09 02:44:38 +00004204 return;
4205 };
4206}
4207
John McCalldc7c5ad2011-07-22 08:53:00 +00004208static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
4209 const AttributeList &attr) {
4210 SourceLocation loc = attr.getLoc();
4211
4212 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
4213
Fariborz Jahanian94d55d72012-04-21 17:51:44 +00004214 if (!method) {
Fariborz Jahanian0e78afb2012-04-20 22:00:46 +00004215 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
Douglas Gregorf6b8b582012-03-14 16:55:17 +00004216 << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
John McCalldc7c5ad2011-07-22 08:53:00 +00004217 return;
4218 }
4219
4220 // Check that the method returns a normal pointer.
4221 QualType resultType = method->getResultType();
Fariborz Jahanianf2e59452011-09-30 20:50:23 +00004222
4223 if (!resultType->isReferenceType() &&
4224 (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
John McCalldc7c5ad2011-07-22 08:53:00 +00004225 S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
4226 << SourceRange(loc)
4227 << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2;
4228
4229 // Drop the attribute.
4230 return;
4231 }
4232
Michael Han51d8c522013-01-24 16:46:58 +00004233 method->addAttr(::new (S.Context)
4234 ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context,
4235 attr.getAttributeSpellingListIndex()));
John McCalldc7c5ad2011-07-22 08:53:00 +00004236}
4237
Fariborz Jahanian84101132012-09-07 23:46:23 +00004238static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
4239 const AttributeList &attr) {
4240 SourceLocation loc = attr.getLoc();
4241 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
4242
4243 if (!method) {
4244 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4245 << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
4246 return;
4247 }
4248 DeclContext *DC = method->getDeclContext();
4249 if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) {
4250 S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
4251 << attr.getName() << 0;
4252 S.Diag(PDecl->getLocation(), diag::note_protocol_decl);
4253 return;
4254 }
4255 if (method->getMethodFamily() == OMF_dealloc) {
4256 S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
4257 << attr.getName() << 1;
4258 return;
4259 }
4260
Michael Han51d8c522013-01-24 16:46:58 +00004261 method->addAttr(::new (S.Context)
4262 ObjCRequiresSuperAttr(attr.getRange(), S.Context,
4263 attr.getAttributeSpellingListIndex()));
Fariborz Jahanian84101132012-09-07 23:46:23 +00004264}
4265
John McCall8dfac0b2011-09-30 05:12:12 +00004266/// Handle cf_audited_transfer and cf_unknown_transfer.
4267static void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
4268 if (!isa<FunctionDecl>(D)) {
4269 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
Douglas Gregorf6b8b582012-03-14 16:55:17 +00004270 << A.getRange() << A.getName() << ExpectedFunction;
John McCall8dfac0b2011-09-30 05:12:12 +00004271 return;
4272 }
4273
Sean Hunt8e083e72012-06-19 23:57:03 +00004274 bool IsAudited = (A.getKind() == AttributeList::AT_CFAuditedTransfer);
John McCall8dfac0b2011-09-30 05:12:12 +00004275
4276 // Check whether there's a conflicting attribute already present.
4277 Attr *Existing;
4278 if (IsAudited) {
4279 Existing = D->getAttr<CFUnknownTransferAttr>();
4280 } else {
4281 Existing = D->getAttr<CFAuditedTransferAttr>();
4282 }
4283 if (Existing) {
4284 S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
4285 << A.getName()
4286 << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
4287 << A.getRange() << Existing->getRange();
4288 return;
4289 }
4290
4291 // All clear; add the attribute.
4292 if (IsAudited) {
Michael Han51d8c522013-01-24 16:46:58 +00004293 D->addAttr(::new (S.Context)
4294 CFAuditedTransferAttr(A.getRange(), S.Context,
4295 A.getAttributeSpellingListIndex()));
John McCall8dfac0b2011-09-30 05:12:12 +00004296 } else {
Michael Han51d8c522013-01-24 16:46:58 +00004297 D->addAttr(::new (S.Context)
4298 CFUnknownTransferAttr(A.getRange(), S.Context,
4299 A.getAttributeSpellingListIndex()));
John McCall8dfac0b2011-09-30 05:12:12 +00004300 }
4301}
4302
John McCallfe98da02011-09-29 07:17:38 +00004303static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
4304 const AttributeList &Attr) {
4305 RecordDecl *RD = dyn_cast<RecordDecl>(D);
4306 if (!RD || RD->isUnion()) {
4307 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
Douglas Gregorf6b8b582012-03-14 16:55:17 +00004308 << Attr.getRange() << Attr.getName() << ExpectedStruct;
John McCallfe98da02011-09-29 07:17:38 +00004309 }
4310
4311 IdentifierInfo *ParmName = Attr.getParameterName();
4312
4313 // In Objective-C, verify that the type names an Objective-C type.
4314 // We don't want to check this outside of ObjC because people sometimes
4315 // do crazy C declarations of Objective-C types.
David Blaikie4e4d0842012-03-11 07:00:24 +00004316 if (ParmName && S.getLangOpts().ObjC1) {
John McCallfe98da02011-09-29 07:17:38 +00004317 // Check for an existing type with this name.
4318 LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(),
4319 Sema::LookupOrdinaryName);
4320 if (S.LookupName(R, Sc)) {
4321 NamedDecl *Target = R.getFoundDecl();
4322 if (Target && !isa<ObjCInterfaceDecl>(Target)) {
4323 S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
4324 S.Diag(Target->getLocStart(), diag::note_declared_at);
4325 }
4326 }
4327 }
4328
Michael Han51d8c522013-01-24 16:46:58 +00004329 D->addAttr(::new (S.Context)
4330 NSBridgedAttr(Attr.getRange(), S.Context, ParmName,
4331 Attr.getAttributeSpellingListIndex()));
John McCallfe98da02011-09-29 07:17:38 +00004332}
4333
Chandler Carruth1b03c872011-07-02 00:01:44 +00004334static void handleObjCOwnershipAttr(Sema &S, Decl *D,
4335 const AttributeList &Attr) {
Chandler Carruth87c44602011-07-01 23:49:12 +00004336 if (hasDeclarator(D)) return;
John McCallf85e1932011-06-15 23:02:42 +00004337
Chandler Carruth87c44602011-07-01 23:49:12 +00004338 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
Douglas Gregorf6b8b582012-03-14 16:55:17 +00004339 << Attr.getRange() << Attr.getName() << ExpectedVariable;
John McCallf85e1932011-06-15 23:02:42 +00004340}
4341
Chandler Carruth1b03c872011-07-02 00:01:44 +00004342static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
4343 const AttributeList &Attr) {
Chandler Carruth87c44602011-07-01 23:49:12 +00004344 if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
Chandler Carruth87c44602011-07-01 23:49:12 +00004345 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
Douglas Gregorf6b8b582012-03-14 16:55:17 +00004346 << Attr.getRange() << Attr.getName() << ExpectedVariable;
John McCallf85e1932011-06-15 23:02:42 +00004347 return;
4348 }
4349
Chandler Carruth87c44602011-07-01 23:49:12 +00004350 ValueDecl *vd = cast<ValueDecl>(D);
John McCallf85e1932011-06-15 23:02:42 +00004351 QualType type = vd->getType();
4352
4353 if (!type->isDependentType() &&
4354 !type->isObjCLifetimeType()) {
Chandler Carruth87c44602011-07-01 23:49:12 +00004355 S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
John McCallf85e1932011-06-15 23:02:42 +00004356 << type;
4357 return;
4358 }
4359
4360 Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
4361
4362 // If we have no lifetime yet, check the lifetime we're presumably
4363 // going to infer.
4364 if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
4365 lifetime = type->getObjCARCImplicitLifetime();
4366
4367 switch (lifetime) {
4368 case Qualifiers::OCL_None:
4369 assert(type->isDependentType() &&
4370 "didn't infer lifetime for non-dependent type?");
4371 break;
4372
4373 case Qualifiers::OCL_Weak: // meaningful
4374 case Qualifiers::OCL_Strong: // meaningful
4375 break;
4376
4377 case Qualifiers::OCL_ExplicitNone:
4378 case Qualifiers::OCL_Autoreleasing:
Chandler Carruth87c44602011-07-01 23:49:12 +00004379 S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
John McCallf85e1932011-06-15 23:02:42 +00004380 << (lifetime == Qualifiers::OCL_Autoreleasing);
4381 break;
4382 }
4383
Chandler Carruth87c44602011-07-01 23:49:12 +00004384 D->addAttr(::new (S.Context)
Michael Han51d8c522013-01-24 16:46:58 +00004385 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context,
4386 Attr.getAttributeSpellingListIndex()));
John McCallf85e1932011-06-15 23:02:42 +00004387}
4388
Francois Pichet11542142010-12-19 06:50:37 +00004389//===----------------------------------------------------------------------===//
4390// Microsoft specific attribute handlers.
4391//===----------------------------------------------------------------------===//
4392
Chandler Carruth1b03c872011-07-02 00:01:44 +00004393static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Francois Pichet62ec1f22011-09-17 17:15:52 +00004394 if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) {
Francois Pichet11542142010-12-19 06:50:37 +00004395 // check the attribute arguments.
Chandler Carruth1731e202011-07-11 23:30:35 +00004396 if (!checkAttributeNumArgs(S, Attr, 1))
Francois Pichet11542142010-12-19 06:50:37 +00004397 return;
Chandler Carruth1731e202011-07-11 23:30:35 +00004398
Francois Pichet11542142010-12-19 06:50:37 +00004399 Expr *Arg = Attr.getArg(0);
4400 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
Douglas Gregor5cee1192011-07-27 05:40:30 +00004401 if (!Str || !Str->isAscii()) {
Francois Pichetd3d3be92010-12-20 01:41:49 +00004402 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
4403 << "uuid" << 1;
4404 return;
4405 }
4406
Chris Lattner5f9e2722011-07-23 10:55:15 +00004407 StringRef StrRef = Str->getString();
Francois Pichetd3d3be92010-12-20 01:41:49 +00004408
4409 bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
4410 StrRef.back() == '}';
Douglas Gregorf6b8b582012-03-14 16:55:17 +00004411
Francois Pichetd3d3be92010-12-20 01:41:49 +00004412 // Validate GUID length.
4413 if (IsCurly && StrRef.size() != 38) {
4414 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4415 return;
4416 }
4417 if (!IsCurly && StrRef.size() != 36) {
4418 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4419 return;
4420 }
4421
Douglas Gregorf6b8b582012-03-14 16:55:17 +00004422 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
Francois Pichetd3d3be92010-12-20 01:41:49 +00004423 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
Chris Lattner5f9e2722011-07-23 10:55:15 +00004424 StringRef::iterator I = StrRef.begin();
Anders Carlssonf89e0422011-01-23 21:07:30 +00004425 if (IsCurly) // Skip the optional '{'
4426 ++I;
4427
4428 for (int i = 0; i < 36; ++i) {
Francois Pichetd3d3be92010-12-20 01:41:49 +00004429 if (i == 8 || i == 13 || i == 18 || i == 23) {
4430 if (*I != '-') {
4431 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4432 return;
4433 }
4434 } else if (!isxdigit(*I)) {
4435 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
4436 return;
4437 }
4438 I++;
4439 }
Francois Pichet11542142010-12-19 06:50:37 +00004440
Michael Han51d8c522013-01-24 16:46:58 +00004441 D->addAttr(::new (S.Context)
4442 UuidAttr(Attr.getRange(), S.Context, Str->getString(),
4443 Attr.getAttributeSpellingListIndex()));
Francois Pichetd3d3be92010-12-20 01:41:49 +00004444 } else
Francois Pichet11542142010-12-19 06:50:37 +00004445 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
Charles Davisf0122fe2010-02-16 18:27:26 +00004446}
4447
John McCallc052dbb2012-05-22 21:28:12 +00004448static void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Nico Weber7b89ab72012-11-07 21:31:36 +00004449 if (!S.LangOpts.MicrosoftExt) {
John McCallc052dbb2012-05-22 21:28:12 +00004450 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
Nico Weber7b89ab72012-11-07 21:31:36 +00004451 return;
4452 }
4453
4454 AttributeList::Kind Kind = Attr.getKind();
4455 if (Kind == AttributeList::AT_SingleInheritance)
4456 D->addAttr(
Michael Han51d8c522013-01-24 16:46:58 +00004457 ::new (S.Context)
4458 SingleInheritanceAttr(Attr.getRange(), S.Context,
4459 Attr.getAttributeSpellingListIndex()));
Nico Weber7b89ab72012-11-07 21:31:36 +00004460 else if (Kind == AttributeList::AT_MultipleInheritance)
4461 D->addAttr(
Michael Han51d8c522013-01-24 16:46:58 +00004462 ::new (S.Context)
4463 MultipleInheritanceAttr(Attr.getRange(), S.Context,
4464 Attr.getAttributeSpellingListIndex()));
Nico Weber7b89ab72012-11-07 21:31:36 +00004465 else if (Kind == AttributeList::AT_VirtualInheritance)
4466 D->addAttr(
Michael Han51d8c522013-01-24 16:46:58 +00004467 ::new (S.Context)
4468 VirtualInheritanceAttr(Attr.getRange(), S.Context,
4469 Attr.getAttributeSpellingListIndex()));
John McCallc052dbb2012-05-22 21:28:12 +00004470}
4471
4472static void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4473 if (S.LangOpts.MicrosoftExt) {
4474 AttributeList::Kind Kind = Attr.getKind();
Sean Hunt8e083e72012-06-19 23:57:03 +00004475 if (Kind == AttributeList::AT_Ptr32)
John McCallc052dbb2012-05-22 21:28:12 +00004476 D->addAttr(
Michael Han51d8c522013-01-24 16:46:58 +00004477 ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context,
4478 Attr.getAttributeSpellingListIndex()));
Sean Hunt8e083e72012-06-19 23:57:03 +00004479 else if (Kind == AttributeList::AT_Ptr64)
John McCallc052dbb2012-05-22 21:28:12 +00004480 D->addAttr(
Michael Han51d8c522013-01-24 16:46:58 +00004481 ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context,
4482 Attr.getAttributeSpellingListIndex()));
Sean Hunt8e083e72012-06-19 23:57:03 +00004483 else if (Kind == AttributeList::AT_Win64)
John McCallc052dbb2012-05-22 21:28:12 +00004484 D->addAttr(
Michael Han51d8c522013-01-24 16:46:58 +00004485 ::new (S.Context) Win64Attr(Attr.getRange(), S.Context,
4486 Attr.getAttributeSpellingListIndex()));
John McCallc052dbb2012-05-22 21:28:12 +00004487 } else
4488 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4489}
4490
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00004491static void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4492 if (S.LangOpts.MicrosoftExt)
Michael Han51d8c522013-01-24 16:46:58 +00004493 D->addAttr(::new (S.Context)
4494 ForceInlineAttr(Attr.getRange(), S.Context,
4495 Attr.getAttributeSpellingListIndex()));
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00004496 else
4497 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4498}
4499
Ted Kremenekb71368d2009-05-09 02:44:38 +00004500//===----------------------------------------------------------------------===//
Chris Lattner0744e5f2008-06-29 00:23:49 +00004501// Top Level Sema Entry Points
4502//===----------------------------------------------------------------------===//
4503
Chandler Carruth1b03c872011-07-02 00:01:44 +00004504static void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
4505 const AttributeList &Attr) {
Peter Collingbourne60700392011-01-21 02:08:45 +00004506 switch (Attr.getKind()) {
Sean Hunt8e083e72012-06-19 23:57:03 +00004507 case AttributeList::AT_CUDADevice: handleDeviceAttr (S, D, Attr); break;
4508 case AttributeList::AT_CUDAHost: handleHostAttr (S, D, Attr); break;
4509 case AttributeList::AT_Overloadable:handleOverloadableAttr(S, D, Attr); break;
Peter Collingbourne60700392011-01-21 02:08:45 +00004510 default:
4511 break;
4512 }
4513}
Abramo Bagnarae215f722010-04-30 13:10:51 +00004514
Chandler Carruth1b03c872011-07-02 00:01:44 +00004515static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
4516 const AttributeList &Attr) {
Chris Lattner803d0802008-06-29 00:43:07 +00004517 switch (Attr.getKind()) {
Richard Smithcd8ab512013-01-17 01:30:42 +00004518 case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break;
4519 case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break;
4520 case AttributeList::AT_IBOutletCollection:
4521 handleIBOutletCollection(S, D, Attr); break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004522 case AttributeList::AT_AddressSpace:
4523 case AttributeList::AT_OpenCLImageAccess:
4524 case AttributeList::AT_ObjCGC:
4525 case AttributeList::AT_VectorSize:
4526 case AttributeList::AT_NeonVectorType:
4527 case AttributeList::AT_NeonPolyVectorType:
Mike Stumpbf916502009-07-24 19:02:52 +00004528 // Ignore these, these are type attributes, handled by
4529 // ProcessTypeAttributes.
Chris Lattner803d0802008-06-29 00:43:07 +00004530 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004531 case AttributeList::AT_CUDADevice:
4532 case AttributeList::AT_CUDAHost:
4533 case AttributeList::AT_Overloadable:
Peter Collingbourne60700392011-01-21 02:08:45 +00004534 // Ignore, this is a non-inheritable attribute, handled
4535 // by ProcessNonInheritableDeclAttr.
4536 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004537 case AttributeList::AT_Alias: handleAliasAttr (S, D, Attr); break;
4538 case AttributeList::AT_Aligned: handleAlignedAttr (S, D, Attr); break;
4539 case AttributeList::AT_AllocSize: handleAllocSizeAttr (S, D, Attr); break;
4540 case AttributeList::AT_AlwaysInline:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004541 handleAlwaysInlineAttr (S, D, Attr); break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004542 case AttributeList::AT_AnalyzerNoReturn:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004543 handleAnalyzerNoReturnAttr (S, D, Attr); break;
Hans Wennborg5e2d5de2012-06-23 11:51:46 +00004544 case AttributeList::AT_TLSModel: handleTLSModelAttr (S, D, Attr); break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004545 case AttributeList::AT_Annotate: handleAnnotateAttr (S, D, Attr); break;
4546 case AttributeList::AT_Availability:handleAvailabilityAttr(S, D, Attr); break;
4547 case AttributeList::AT_CarriesDependency:
Richard Smith3a2b7a12013-01-28 22:42:45 +00004548 handleDependencyAttr(S, scope, D, Attr);
4549 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004550 case AttributeList::AT_Common: handleCommonAttr (S, D, Attr); break;
4551 case AttributeList::AT_CUDAConstant:handleConstantAttr (S, D, Attr); break;
4552 case AttributeList::AT_Constructor: handleConstructorAttr (S, D, Attr); break;
Richard Smithcd8ab512013-01-17 01:30:42 +00004553 case AttributeList::AT_CXX11NoReturn:
4554 handleCXX11NoReturnAttr(S, D, Attr);
4555 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004556 case AttributeList::AT_Deprecated:
Benjamin Kramerbc3260d2012-05-16 12:19:08 +00004557 handleAttrWithMessage<DeprecatedAttr>(S, D, Attr, "deprecated");
4558 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004559 case AttributeList::AT_Destructor: handleDestructorAttr (S, D, Attr); break;
4560 case AttributeList::AT_ExtVectorType:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004561 handleExtVectorTypeAttr(S, scope, D, Attr);
Chris Lattner803d0802008-06-29 00:43:07 +00004562 break;
Quentin Colombetaee56fa2012-11-01 23:55:47 +00004563 case AttributeList::AT_MinSize:
4564 handleMinSizeAttr(S, D, Attr);
4565 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004566 case AttributeList::AT_Format: handleFormatAttr (S, D, Attr); break;
4567 case AttributeList::AT_FormatArg: handleFormatArgAttr (S, D, Attr); break;
4568 case AttributeList::AT_CUDAGlobal: handleGlobalAttr (S, D, Attr); break;
4569 case AttributeList::AT_GNUInline: handleGNUInlineAttr (S, D, Attr); break;
4570 case AttributeList::AT_CUDALaunchBounds:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004571 handleLaunchBoundsAttr(S, D, Attr);
Peter Collingbourne7b381982010-12-12 23:03:07 +00004572 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004573 case AttributeList::AT_Mode: handleModeAttr (S, D, Attr); break;
4574 case AttributeList::AT_Malloc: handleMallocAttr (S, D, Attr); break;
4575 case AttributeList::AT_MayAlias: handleMayAliasAttr (S, D, Attr); break;
4576 case AttributeList::AT_NoCommon: handleNoCommonAttr (S, D, Attr); break;
4577 case AttributeList::AT_NonNull: handleNonNullAttr (S, D, Attr); break;
Ted Kremenekdd0e4902010-07-31 01:52:11 +00004578 case AttributeList::AT_ownership_returns:
4579 case AttributeList::AT_ownership_takes:
4580 case AttributeList::AT_ownership_holds:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004581 handleOwnershipAttr (S, D, Attr); break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004582 case AttributeList::AT_Cold: handleColdAttr (S, D, Attr); break;
4583 case AttributeList::AT_Hot: handleHotAttr (S, D, Attr); break;
4584 case AttributeList::AT_Naked: handleNakedAttr (S, D, Attr); break;
4585 case AttributeList::AT_NoReturn: handleNoReturnAttr (S, D, Attr); break;
4586 case AttributeList::AT_NoThrow: handleNothrowAttr (S, D, Attr); break;
4587 case AttributeList::AT_CUDAShared: handleSharedAttr (S, D, Attr); break;
4588 case AttributeList::AT_VecReturn: handleVecReturnAttr (S, D, Attr); break;
Ted Kremenekb71368d2009-05-09 02:44:38 +00004589
Sean Hunt8e083e72012-06-19 23:57:03 +00004590 case AttributeList::AT_ObjCOwnership:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004591 handleObjCOwnershipAttr(S, D, Attr); break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004592 case AttributeList::AT_ObjCPreciseLifetime:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004593 handleObjCPreciseLifetimeAttr(S, D, Attr); break;
John McCallf85e1932011-06-15 23:02:42 +00004594
Sean Hunt8e083e72012-06-19 23:57:03 +00004595 case AttributeList::AT_ObjCReturnsInnerPointer:
John McCalldc7c5ad2011-07-22 08:53:00 +00004596 handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
4597
Fariborz Jahanian84101132012-09-07 23:46:23 +00004598 case AttributeList::AT_ObjCRequiresSuper:
4599 handleObjCRequiresSuperAttr(S, D, Attr); break;
4600
Sean Hunt8e083e72012-06-19 23:57:03 +00004601 case AttributeList::AT_NSBridged:
John McCallfe98da02011-09-29 07:17:38 +00004602 handleNSBridgedAttr(S, scope, D, Attr); break;
4603
Sean Hunt8e083e72012-06-19 23:57:03 +00004604 case AttributeList::AT_CFAuditedTransfer:
4605 case AttributeList::AT_CFUnknownTransfer:
John McCall8dfac0b2011-09-30 05:12:12 +00004606 handleCFTransferAttr(S, D, Attr); break;
4607
Ted Kremenekb71368d2009-05-09 02:44:38 +00004608 // Checker-specific.
Sean Hunt8e083e72012-06-19 23:57:03 +00004609 case AttributeList::AT_CFConsumed:
4610 case AttributeList::AT_NSConsumed: handleNSConsumedAttr (S, D, Attr); break;
4611 case AttributeList::AT_NSConsumesSelf:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004612 handleNSConsumesSelfAttr(S, D, Attr); break;
John McCallc7ad3812011-01-25 03:31:58 +00004613
Sean Hunt8e083e72012-06-19 23:57:03 +00004614 case AttributeList::AT_NSReturnsAutoreleased:
4615 case AttributeList::AT_NSReturnsNotRetained:
4616 case AttributeList::AT_CFReturnsNotRetained:
4617 case AttributeList::AT_NSReturnsRetained:
4618 case AttributeList::AT_CFReturnsRetained:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004619 handleNSReturnsRetainedAttr(S, D, Attr); break;
Ted Kremenekb71368d2009-05-09 02:44:38 +00004620
Tanya Lattner0df579e2012-07-09 22:06:01 +00004621 case AttributeList::AT_WorkGroupSizeHint:
Sean Hunt8e083e72012-06-19 23:57:03 +00004622 case AttributeList::AT_ReqdWorkGroupSize:
Tanya Lattner0df579e2012-07-09 22:06:01 +00004623 handleWorkGroupSize(S, D, Attr); break;
Nate Begeman6f3d8382009-06-26 06:32:41 +00004624
Sean Hunt8e083e72012-06-19 23:57:03 +00004625 case AttributeList::AT_InitPriority:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004626 handleInitPriorityAttr(S, D, Attr); break;
Fariborz Jahanian521f12d2010-06-18 21:44:06 +00004627
Sean Hunt8e083e72012-06-19 23:57:03 +00004628 case AttributeList::AT_Packed: handlePackedAttr (S, D, Attr); break;
4629 case AttributeList::AT_Section: handleSectionAttr (S, D, Attr); break;
4630 case AttributeList::AT_Unavailable:
Benjamin Kramerbc3260d2012-05-16 12:19:08 +00004631 handleAttrWithMessage<UnavailableAttr>(S, D, Attr, "unavailable");
4632 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004633 case AttributeList::AT_ArcWeakrefUnavailable:
Fariborz Jahanian742352a2011-07-06 19:24:05 +00004634 handleArcWeakrefUnavailableAttr (S, D, Attr);
4635 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004636 case AttributeList::AT_ObjCRootClass:
Patrick Beardb2f68202012-04-06 18:12:22 +00004637 handleObjCRootClassAttr(S, D, Attr);
4638 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004639 case AttributeList::AT_ObjCRequiresPropertyDefs:
Ted Kremenek71207fc2012-01-05 22:47:47 +00004640 handleObjCRequiresPropertyDefsAttr (S, D, Attr);
Fariborz Jahaniane23dcf32012-01-03 18:45:41 +00004641 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004642 case AttributeList::AT_Unused: handleUnusedAttr (S, D, Attr); break;
4643 case AttributeList::AT_ReturnsTwice:
Rafael Espindolaf87cced2011-10-03 14:59:42 +00004644 handleReturnsTwiceAttr(S, D, Attr);
4645 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004646 case AttributeList::AT_Used: handleUsedAttr (S, D, Attr); break;
4647 case AttributeList::AT_Visibility: handleVisibilityAttr (S, D, Attr); break;
4648 case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr);
Chris Lattner026dc962009-02-14 07:37:35 +00004649 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004650 case AttributeList::AT_Weak: handleWeakAttr (S, D, Attr); break;
4651 case AttributeList::AT_WeakRef: handleWeakRefAttr (S, D, Attr); break;
4652 case AttributeList::AT_WeakImport: handleWeakImportAttr (S, D, Attr); break;
4653 case AttributeList::AT_TransparentUnion:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004654 handleTransparentUnionAttr(S, D, Attr);
Chris Lattner803d0802008-06-29 00:43:07 +00004655 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004656 case AttributeList::AT_ObjCException:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004657 handleObjCExceptionAttr(S, D, Attr);
Chris Lattner0db29ec2009-02-14 08:09:34 +00004658 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004659 case AttributeList::AT_ObjCMethodFamily:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004660 handleObjCMethodFamilyAttr(S, D, Attr);
John McCalld5313b02011-03-02 11:33:24 +00004661 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004662 case AttributeList::AT_ObjCNSObject:handleObjCNSObject (S, D, Attr); break;
4663 case AttributeList::AT_Blocks: handleBlocksAttr (S, D, Attr); break;
4664 case AttributeList::AT_Sentinel: handleSentinelAttr (S, D, Attr); break;
4665 case AttributeList::AT_Const: handleConstAttr (S, D, Attr); break;
4666 case AttributeList::AT_Pure: handlePureAttr (S, D, Attr); break;
4667 case AttributeList::AT_Cleanup: handleCleanupAttr (S, D, Attr); break;
4668 case AttributeList::AT_NoDebug: handleNoDebugAttr (S, D, Attr); break;
4669 case AttributeList::AT_NoInline: handleNoInlineAttr (S, D, Attr); break;
4670 case AttributeList::AT_Regparm: handleRegparmAttr (S, D, Attr); break;
Mike Stumpbf916502009-07-24 19:02:52 +00004671 case AttributeList::IgnoredAttribute:
Anders Carlsson05f8e472009-02-13 08:16:43 +00004672 // Just ignore
4673 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004674 case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg.
Chandler Carruth1b03c872011-07-02 00:01:44 +00004675 handleNoInstrumentFunctionAttr(S, D, Attr);
Chris Lattner7255a2d2010-06-22 00:03:40 +00004676 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004677 case AttributeList::AT_StdCall:
4678 case AttributeList::AT_CDecl:
4679 case AttributeList::AT_FastCall:
4680 case AttributeList::AT_ThisCall:
4681 case AttributeList::AT_Pascal:
4682 case AttributeList::AT_Pcs:
Derek Schuff263366f2012-10-16 22:30:41 +00004683 case AttributeList::AT_PnaclCall:
Guy Benyei38980082012-12-25 08:53:55 +00004684 case AttributeList::AT_IntelOclBicc:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004685 handleCallConvAttr(S, D, Attr);
John McCall04a67a62010-02-05 21:31:56 +00004686 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004687 case AttributeList::AT_OpenCLKernel:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004688 handleOpenCLKernelAttr(S, D, Attr);
Peter Collingbournef315fa82011-02-14 01:42:53 +00004689 break;
John McCallc052dbb2012-05-22 21:28:12 +00004690
4691 // Microsoft attributes:
Sean Hunt8e083e72012-06-19 23:57:03 +00004692 case AttributeList::AT_MsStruct:
John McCallc052dbb2012-05-22 21:28:12 +00004693 handleMsStructAttr(S, D, Attr);
4694 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004695 case AttributeList::AT_Uuid:
Chandler Carruth1b03c872011-07-02 00:01:44 +00004696 handleUuidAttr(S, D, Attr);
Francois Pichet11542142010-12-19 06:50:37 +00004697 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004698 case AttributeList::AT_SingleInheritance:
4699 case AttributeList::AT_MultipleInheritance:
4700 case AttributeList::AT_VirtualInheritance:
John McCallc052dbb2012-05-22 21:28:12 +00004701 handleInheritanceAttr(S, D, Attr);
4702 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004703 case AttributeList::AT_Win64:
4704 case AttributeList::AT_Ptr32:
4705 case AttributeList::AT_Ptr64:
John McCallc052dbb2012-05-22 21:28:12 +00004706 handlePortabilityAttr(S, D, Attr);
4707 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004708 case AttributeList::AT_ForceInline:
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00004709 handleForceInlineAttr(S, D, Attr);
4710 break;
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +00004711
4712 // Thread safety attributes:
Sean Hunt8e083e72012-06-19 23:57:03 +00004713 case AttributeList::AT_GuardedVar:
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +00004714 handleGuardedVarAttr(S, D, Attr);
4715 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004716 case AttributeList::AT_PtGuardedVar:
Michael Handc691572012-07-23 18:48:41 +00004717 handlePtGuardedVarAttr(S, D, Attr);
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +00004718 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004719 case AttributeList::AT_ScopedLockable:
Michael Handc691572012-07-23 18:48:41 +00004720 handleScopedLockableAttr(S, D, Attr);
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +00004721 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004722 case AttributeList::AT_NoAddressSafetyAnalysis:
Kostya Serebryany71efba02012-01-24 19:25:38 +00004723 handleNoAddressSafetyAttr(S, D, Attr);
4724 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004725 case AttributeList::AT_NoThreadSafetyAnalysis:
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +00004726 handleNoThreadSafetyAttr(S, D, Attr);
4727 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004728 case AttributeList::AT_Lockable:
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +00004729 handleLockableAttr(S, D, Attr);
4730 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004731 case AttributeList::AT_GuardedBy:
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004732 handleGuardedByAttr(S, D, Attr);
4733 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004734 case AttributeList::AT_PtGuardedBy:
Michael Handc691572012-07-23 18:48:41 +00004735 handlePtGuardedByAttr(S, D, Attr);
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004736 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004737 case AttributeList::AT_ExclusiveLockFunction:
Michael Handc691572012-07-23 18:48:41 +00004738 handleExclusiveLockFunctionAttr(S, D, Attr);
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004739 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004740 case AttributeList::AT_ExclusiveLocksRequired:
Michael Handc691572012-07-23 18:48:41 +00004741 handleExclusiveLocksRequiredAttr(S, D, Attr);
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004742 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004743 case AttributeList::AT_ExclusiveTrylockFunction:
Michael Handc691572012-07-23 18:48:41 +00004744 handleExclusiveTrylockFunctionAttr(S, D, Attr);
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004745 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004746 case AttributeList::AT_LockReturned:
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004747 handleLockReturnedAttr(S, D, Attr);
4748 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004749 case AttributeList::AT_LocksExcluded:
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004750 handleLocksExcludedAttr(S, D, Attr);
4751 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004752 case AttributeList::AT_SharedLockFunction:
Michael Handc691572012-07-23 18:48:41 +00004753 handleSharedLockFunctionAttr(S, D, Attr);
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004754 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004755 case AttributeList::AT_SharedLocksRequired:
Michael Handc691572012-07-23 18:48:41 +00004756 handleSharedLocksRequiredAttr(S, D, Attr);
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004757 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004758 case AttributeList::AT_SharedTrylockFunction:
Michael Handc691572012-07-23 18:48:41 +00004759 handleSharedTrylockFunctionAttr(S, D, Attr);
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004760 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004761 case AttributeList::AT_UnlockFunction:
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004762 handleUnlockFunAttr(S, D, Attr);
4763 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004764 case AttributeList::AT_AcquiredBefore:
Michael Handc691572012-07-23 18:48:41 +00004765 handleAcquiredBeforeAttr(S, D, Attr);
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004766 break;
Sean Hunt8e083e72012-06-19 23:57:03 +00004767 case AttributeList::AT_AcquiredAfter:
Michael Handc691572012-07-23 18:48:41 +00004768 handleAcquiredAfterAttr(S, D, Attr);
Caitlin Sadowskidb33e142011-07-28 20:12:35 +00004769 break;
Caitlin Sadowskifdde9e72011-07-28 17:21:07 +00004770
Dmitri Gribenko0d5a0692012-08-17 00:08:38 +00004771 // Type safety attributes.
4772 case AttributeList::AT_ArgumentWithTypeTag:
4773 handleArgumentWithTypeTagAttr(S, D, Attr);
4774 break;
4775 case AttributeList::AT_TypeTagForDatatype:
4776 handleTypeTagForDatatypeAttr(S, D, Attr);
4777 break;
4778
Chris Lattner803d0802008-06-29 00:43:07 +00004779 default:
Anton Korobeynikov82d0a412010-01-10 12:58:08 +00004780 // Ask target about the attribute.
4781 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
4782 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
Aaron Ballmanfc685ac2012-06-19 22:09:27 +00004783 S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ?
4784 diag::warn_unhandled_ms_attribute_ignored :
4785 diag::warn_unknown_attribute_ignored) << Attr.getName();
Chris Lattner803d0802008-06-29 00:43:07 +00004786 break;
4787 }
4788}
4789
Peter Collingbourne60700392011-01-21 02:08:45 +00004790/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
4791/// the attribute applies to decls. If the attribute is a type attribute, just
Richard Smithcd8ab512013-01-17 01:30:42 +00004792/// silently ignore it if a GNU attribute.
Chandler Carruth1b03c872011-07-02 00:01:44 +00004793static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
4794 const AttributeList &Attr,
Richard Smithcd8ab512013-01-17 01:30:42 +00004795 bool NonInheritable, bool Inheritable,
4796 bool IncludeCXX11Attributes) {
Peter Collingbourne60700392011-01-21 02:08:45 +00004797 if (Attr.isInvalid())
4798 return;
4799
Richard Smithcd8ab512013-01-17 01:30:42 +00004800 // Ignore C++11 attributes on declarator chunks: they appertain to the type
4801 // instead.
4802 if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes)
4803 return;
4804
Peter Collingbourne60700392011-01-21 02:08:45 +00004805 if (NonInheritable)
Chandler Carruth1b03c872011-07-02 00:01:44 +00004806 ProcessNonInheritableDeclAttr(S, scope, D, Attr);
Peter Collingbourne60700392011-01-21 02:08:45 +00004807
4808 if (Inheritable)
Chandler Carruth1b03c872011-07-02 00:01:44 +00004809 ProcessInheritableDeclAttr(S, scope, D, Attr);
Peter Collingbourne60700392011-01-21 02:08:45 +00004810}
4811
Chris Lattner803d0802008-06-29 00:43:07 +00004812/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
4813/// attribute list to the specified decl, ignoring any type attributes.
Eric Christopherf48f3672010-12-01 22:13:54 +00004814void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
Peter Collingbourne60700392011-01-21 02:08:45 +00004815 const AttributeList *AttrList,
Richard Smithcd8ab512013-01-17 01:30:42 +00004816 bool NonInheritable, bool Inheritable,
4817 bool IncludeCXX11Attributes) {
4818 for (const AttributeList* l = AttrList; l; l = l->getNext())
4819 ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable,
4820 IncludeCXX11Attributes);
Rafael Espindola11e8ce72010-02-23 22:00:30 +00004821
4822 // GCC accepts
4823 // static int a9 __attribute__((weakref));
4824 // but that looks really pointless. We reject it.
Peter Collingbourne60700392011-01-21 02:08:45 +00004825 if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
Rafael Espindola11e8ce72010-02-23 22:00:30 +00004826 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
Rafael Espindola4d8a33b2013-01-16 23:49:06 +00004827 cast<NamedDecl>(D)->getNameAsString();
4828 D->dropAttr<WeakRefAttr>();
Rafael Espindola11e8ce72010-02-23 22:00:30 +00004829 return;
Chris Lattner803d0802008-06-29 00:43:07 +00004830 }
4831}
4832
Erik Verbruggen5f1c8222011-10-13 09:41:32 +00004833// Annotation attributes are the only attributes allowed after an access
4834// specifier.
4835bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
4836 const AttributeList *AttrList) {
4837 for (const AttributeList* l = AttrList; l; l = l->getNext()) {
Sean Hunt8e083e72012-06-19 23:57:03 +00004838 if (l->getKind() == AttributeList::AT_Annotate) {
Erik Verbruggen5f1c8222011-10-13 09:41:32 +00004839 handleAnnotateAttr(*this, ASDecl, *l);
4840 } else {
4841 Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
4842 return true;
4843 }
4844 }
4845
4846 return false;
4847}
4848
John McCalle82247a2011-10-01 05:17:03 +00004849/// checkUnusedDeclAttributes - Check a list of attributes to see if it
4850/// contains any decl attributes that we should warn about.
4851static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
4852 for ( ; A; A = A->getNext()) {
4853 // Only warn if the attribute is an unignored, non-type attribute.
Richard Smithd03de6a2013-01-29 10:02:16 +00004854 if (A->isUsedAsTypeAttr() || A->isInvalid()) continue;
John McCalle82247a2011-10-01 05:17:03 +00004855 if (A->getKind() == AttributeList::IgnoredAttribute) continue;
4856
4857 if (A->getKind() == AttributeList::UnknownAttribute) {
4858 S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
4859 << A->getName() << A->getRange();
4860 } else {
4861 S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
4862 << A->getName() << A->getRange();
4863 }
4864 }
4865}
4866
4867/// checkUnusedDeclAttributes - Given a declarator which is not being
4868/// used to build a declaration, complain about any decl attributes
4869/// which might be lying around on it.
4870void Sema::checkUnusedDeclAttributes(Declarator &D) {
4871 ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
4872 ::checkUnusedDeclAttributes(*this, D.getAttributes());
4873 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
4874 ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
4875}
4876
Ryan Flynne25ff832009-07-30 03:15:39 +00004877/// DeclClonePragmaWeak - clone existing decl (maybe definition),
James Dennett1dfbd922012-06-14 21:40:34 +00004878/// \#pragma weak needs a non-definition decl and source may not have one.
Eli Friedman900693b2011-09-07 04:05:06 +00004879NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
4880 SourceLocation Loc) {
Ryan Flynn7b1fdbd2009-07-31 02:52:19 +00004881 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
Ryan Flynne25ff832009-07-30 03:15:39 +00004882 NamedDecl *NewD = 0;
4883 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
Eli Friedman900693b2011-09-07 04:05:06 +00004884 FunctionDecl *NewFD;
4885 // FIXME: Missing call to CheckFunctionDeclaration().
4886 // FIXME: Mangling?
4887 // FIXME: Is the qualifier info correct?
4888 // FIXME: Is the DeclContext correct?
4889 NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
4890 Loc, Loc, DeclarationName(II),
4891 FD->getType(), FD->getTypeSourceInfo(),
4892 SC_None, SC_None,
4893 false/*isInlineSpecified*/,
4894 FD->hasPrototype(),
4895 false/*isConstexprSpecified*/);
4896 NewD = NewFD;
4897
4898 if (FD->getQualifier())
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00004899 NewFD->setQualifierInfo(FD->getQualifierLoc());
Eli Friedman900693b2011-09-07 04:05:06 +00004900
4901 // Fake up parameter variables; they are declared as if this were
4902 // a typedef.
4903 QualType FDTy = FD->getType();
4904 if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
4905 SmallVector<ParmVarDecl*, 16> Params;
4906 for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
4907 AE = FT->arg_type_end(); AI != AE; ++AI) {
4908 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
4909 Param->setScopeInfo(0, Params.size());
4910 Params.push_back(Param);
4911 }
David Blaikie4278c652011-09-21 18:16:56 +00004912 NewFD->setParams(Params);
John McCallb6217662010-03-15 10:12:16 +00004913 }
Ryan Flynne25ff832009-07-30 03:15:39 +00004914 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
4915 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
Abramo Bagnaraff676cb2011-03-08 08:55:46 +00004916 VD->getInnerLocStart(), VD->getLocation(), II,
John McCalla93c9342009-12-07 02:54:59 +00004917 VD->getType(), VD->getTypeSourceInfo(),
Douglas Gregor16573fa2010-04-19 22:54:31 +00004918 VD->getStorageClass(),
4919 VD->getStorageClassAsWritten());
John McCallb6217662010-03-15 10:12:16 +00004920 if (VD->getQualifier()) {
4921 VarDecl *NewVD = cast<VarDecl>(NewD);
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00004922 NewVD->setQualifierInfo(VD->getQualifierLoc());
John McCallb6217662010-03-15 10:12:16 +00004923 }
Ryan Flynne25ff832009-07-30 03:15:39 +00004924 }
4925 return NewD;
4926}
4927
James Dennett1dfbd922012-06-14 21:40:34 +00004928/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak
Ryan Flynne25ff832009-07-30 03:15:39 +00004929/// applied to it, possibly with an alias.
Ryan Flynn7b1fdbd2009-07-31 02:52:19 +00004930void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
Chris Lattnerc4f1fb12009-09-08 18:10:11 +00004931 if (W.getUsed()) return; // only do this once
4932 W.setUsed(true);
4933 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
4934 IdentifierInfo *NDId = ND->getIdentifier();
Eli Friedman900693b2011-09-07 04:05:06 +00004935 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
Sean Huntcf807c42010-08-18 23:23:40 +00004936 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
4937 NDId->getName()));
4938 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
Chris Lattnerc4f1fb12009-09-08 18:10:11 +00004939 WeakTopLevelDecl.push_back(NewD);
4940 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
4941 // to insert Decl at TU scope, sorry.
4942 DeclContext *SavedContext = CurContext;
4943 CurContext = Context.getTranslationUnitDecl();
4944 PushOnScopeChains(NewD, S);
4945 CurContext = SavedContext;
4946 } else { // just add weak to existing
Sean Huntcf807c42010-08-18 23:23:40 +00004947 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
Ryan Flynne25ff832009-07-30 03:15:39 +00004948 }
4949}
4950
Chris Lattner0744e5f2008-06-29 00:23:49 +00004951/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
4952/// it, apply them to D. This is a bit tricky because PD can have attributes
4953/// specified in many different places, and we need to find and apply them all.
Peter Collingbourne60700392011-01-21 02:08:45 +00004954void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
4955 bool NonInheritable, bool Inheritable) {
John McCalld4aff0e2010-10-27 00:59:00 +00004956 // It's valid to "forward-declare" #pragma weak, in which case we
4957 // have to do this.
Douglas Gregor31e37b22011-07-28 18:09:57 +00004958 if (Inheritable) {
4959 LoadExternalWeakUndeclaredIdentifiers();
4960 if (!WeakUndeclaredIdentifiers.empty()) {
4961 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
4962 if (IdentifierInfo *Id = ND->getIdentifier()) {
4963 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
4964 = WeakUndeclaredIdentifiers.find(Id);
4965 if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
4966 WeakInfo W = I->second;
4967 DeclApplyPragmaWeak(S, ND, W);
4968 WeakUndeclaredIdentifiers[Id] = W;
4969 }
John McCalld4aff0e2010-10-27 00:59:00 +00004970 }
Ryan Flynne25ff832009-07-30 03:15:39 +00004971 }
4972 }
4973 }
4974
Chris Lattner0744e5f2008-06-29 00:23:49 +00004975 // Apply decl attributes from the DeclSpec if present.
John McCall7f040a92010-12-24 02:08:15 +00004976 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
Peter Collingbourne60700392011-01-21 02:08:45 +00004977 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
Mike Stumpbf916502009-07-24 19:02:52 +00004978
Chris Lattner0744e5f2008-06-29 00:23:49 +00004979 // Walk the declarator structure, applying decl attributes that were in a type
4980 // position to the decl itself. This handles cases like:
4981 // int *__attr__(x)** D;
4982 // when X is a decl attribute.
4983 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
4984 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
Richard Smithcd8ab512013-01-17 01:30:42 +00004985 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable,
4986 /*IncludeCXX11Attributes=*/false);
Mike Stumpbf916502009-07-24 19:02:52 +00004987
Chris Lattner0744e5f2008-06-29 00:23:49 +00004988 // Finally, apply any attributes on the decl itself.
4989 if (const AttributeList *Attrs = PD.getAttributes())
Peter Collingbourne60700392011-01-21 02:08:45 +00004990 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
Chris Lattner0744e5f2008-06-29 00:23:49 +00004991}
John McCall54abf7d2009-11-04 02:18:39 +00004992
John McCallf85e1932011-06-15 23:02:42 +00004993/// Is the given declaration allowed to use a forbidden type?
4994static bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
4995 // Private ivars are always okay. Unfortunately, people don't
4996 // always properly make their ivars private, even in system headers.
4997 // Plus we need to make fields okay, too.
Fariborz Jahaniana6b33802011-09-26 21:23:35 +00004998 // Function declarations in sys headers will be marked unavailable.
4999 if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
5000 !isa<FunctionDecl>(decl))
John McCallf85e1932011-06-15 23:02:42 +00005001 return false;
5002
5003 // Require it to be declared in a system header.
5004 return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
5005}
5006
5007/// Handle a delayed forbidden-type diagnostic.
5008static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
5009 Decl *decl) {
5010 if (decl && isForbiddenTypeAllowed(S, decl)) {
5011 decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
5012 "this system declaration uses an unsupported type"));
5013 return;
5014 }
David Blaikie4e4d0842012-03-11 07:00:24 +00005015 if (S.getLangOpts().ObjCAutoRefCount)
Fariborz Jahanian175fb102011-10-03 22:11:57 +00005016 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
Benjamin Kramer48d798c2012-06-02 10:20:41 +00005017 // FIXME: we may want to suppress diagnostics for all
Fariborz Jahanian175fb102011-10-03 22:11:57 +00005018 // kind of forbidden type messages on unavailable functions.
5019 if (FD->hasAttr<UnavailableAttr>() &&
5020 diag.getForbiddenTypeDiagnostic() ==
5021 diag::err_arc_array_param_no_ownership) {
5022 diag.Triggered = true;
5023 return;
5024 }
5025 }
John McCallf85e1932011-06-15 23:02:42 +00005026
5027 S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
5028 << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
5029 diag.Triggered = true;
5030}
5031
John McCall92576642012-05-07 06:16:41 +00005032void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
5033 assert(DelayedDiagnostics.getCurrentPool());
John McCall13489672012-05-07 06:16:58 +00005034 DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
John McCall92576642012-05-07 06:16:41 +00005035 DelayedDiagnostics.popWithoutEmitting(state);
John McCalleee1d542011-02-14 07:13:47 +00005036
John McCall92576642012-05-07 06:16:41 +00005037 // When delaying diagnostics to run in the context of a parsed
5038 // declaration, we only want to actually emit anything if parsing
5039 // succeeds.
5040 if (!decl) return;
John McCalleee1d542011-02-14 07:13:47 +00005041
John McCall92576642012-05-07 06:16:41 +00005042 // We emit all the active diagnostics in this pool or any of its
5043 // parents. In general, we'll get one pool for the decl spec
5044 // and a child pool for each declarator; in a decl group like:
5045 // deprecated_typedef foo, *bar, baz();
5046 // only the declarator pops will be passed decls. This is correct;
5047 // we really do need to consider delayed diagnostics from the decl spec
5048 // for each of the different declarations.
John McCall13489672012-05-07 06:16:58 +00005049 const DelayedDiagnosticPool *pool = &poppedPool;
John McCall92576642012-05-07 06:16:41 +00005050 do {
John McCall13489672012-05-07 06:16:58 +00005051 for (DelayedDiagnosticPool::pool_iterator
John McCall92576642012-05-07 06:16:41 +00005052 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
5053 // This const_cast is a bit lame. Really, Triggered should be mutable.
5054 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
John McCalleee1d542011-02-14 07:13:47 +00005055 if (diag.Triggered)
John McCall2f514482010-01-27 03:50:35 +00005056 continue;
5057
John McCalleee1d542011-02-14 07:13:47 +00005058 switch (diag.Kind) {
John McCall2f514482010-01-27 03:50:35 +00005059 case DelayedDiagnostic::Deprecation:
John McCalle8c904f2012-01-26 20:04:03 +00005060 // Don't bother giving deprecation diagnostics if the decl is invalid.
5061 if (!decl->isInvalidDecl())
John McCall92576642012-05-07 06:16:41 +00005062 HandleDelayedDeprecationCheck(diag, decl);
John McCall2f514482010-01-27 03:50:35 +00005063 break;
5064
5065 case DelayedDiagnostic::Access:
John McCall92576642012-05-07 06:16:41 +00005066 HandleDelayedAccessCheck(diag, decl);
John McCall2f514482010-01-27 03:50:35 +00005067 break;
John McCallf85e1932011-06-15 23:02:42 +00005068
5069 case DelayedDiagnostic::ForbiddenType:
John McCall92576642012-05-07 06:16:41 +00005070 handleDelayedForbiddenType(*this, diag, decl);
John McCallf85e1932011-06-15 23:02:42 +00005071 break;
John McCall2f514482010-01-27 03:50:35 +00005072 }
5073 }
John McCall92576642012-05-07 06:16:41 +00005074 } while ((pool = pool->getParent()));
John McCall54abf7d2009-11-04 02:18:39 +00005075}
5076
John McCall13489672012-05-07 06:16:58 +00005077/// Given a set of delayed diagnostics, re-emit them as if they had
5078/// been delayed in the current context instead of in the given pool.
5079/// Essentially, this just moves them to the current pool.
5080void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
5081 DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
5082 assert(curPool && "re-emitting in undelayed context not supported");
5083 curPool->steal(pool);
5084}
5085
John McCall54abf7d2009-11-04 02:18:39 +00005086static bool isDeclDeprecated(Decl *D) {
5087 do {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00005088 if (D->isDeprecated())
John McCall54abf7d2009-11-04 02:18:39 +00005089 return true;
Argyrios Kyrtzidisc076e372011-10-06 23:23:27 +00005090 // A category implicitly has the availability of the interface.
5091 if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
5092 return CatD->getClassInterface()->isDeprecated();
John McCall54abf7d2009-11-04 02:18:39 +00005093 } while ((D = cast_or_null<Decl>(D->getDeclContext())));
5094 return false;
5095}
5096
Eli Friedmanc3b23082012-08-08 21:52:41 +00005097static void
5098DoEmitDeprecationWarning(Sema &S, const NamedDecl *D, StringRef Message,
5099 SourceLocation Loc,
Fariborz Jahanianfd090882012-09-21 20:46:37 +00005100 const ObjCInterfaceDecl *UnknownObjCClass,
5101 const ObjCPropertyDecl *ObjCPropery) {
Eli Friedmanc3b23082012-08-08 21:52:41 +00005102 DeclarationName Name = D->getDeclName();
5103 if (!Message.empty()) {
5104 S.Diag(Loc, diag::warn_deprecated_message) << Name << Message;
5105 S.Diag(D->getLocation(),
5106 isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
5107 : diag::note_previous_decl) << Name;
Fariborz Jahanianfd090882012-09-21 20:46:37 +00005108 if (ObjCPropery)
5109 S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute)
5110 << ObjCPropery->getDeclName() << 0;
Eli Friedmanc3b23082012-08-08 21:52:41 +00005111 } else if (!UnknownObjCClass) {
5112 S.Diag(Loc, diag::warn_deprecated) << D->getDeclName();
5113 S.Diag(D->getLocation(),
5114 isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
5115 : diag::note_previous_decl) << Name;
Fariborz Jahanianfd090882012-09-21 20:46:37 +00005116 if (ObjCPropery)
5117 S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute)
5118 << ObjCPropery->getDeclName() << 0;
Eli Friedmanc3b23082012-08-08 21:52:41 +00005119 } else {
5120 S.Diag(Loc, diag::warn_deprecated_fwdclass_message) << Name;
5121 S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
5122 }
5123}
5124
John McCall9c3087b2010-08-26 02:13:20 +00005125void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
John McCall2f514482010-01-27 03:50:35 +00005126 Decl *Ctx) {
5127 if (isDeclDeprecated(Ctx))
John McCall54abf7d2009-11-04 02:18:39 +00005128 return;
5129
John McCall2f514482010-01-27 03:50:35 +00005130 DD.Triggered = true;
Eli Friedmanc3b23082012-08-08 21:52:41 +00005131 DoEmitDeprecationWarning(*this, DD.getDeprecationDecl(),
5132 DD.getDeprecationMessage(), DD.Loc,
Fariborz Jahanianfd090882012-09-21 20:46:37 +00005133 DD.getUnknownObjCClass(),
5134 DD.getObjCProperty());
John McCall54abf7d2009-11-04 02:18:39 +00005135}
5136
Chris Lattner5f9e2722011-07-23 10:55:15 +00005137void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
Fariborz Jahanian8e5fc9b2010-12-21 00:44:01 +00005138 SourceLocation Loc,
Fariborz Jahanianfd090882012-09-21 20:46:37 +00005139 const ObjCInterfaceDecl *UnknownObjCClass,
5140 const ObjCPropertyDecl *ObjCProperty) {
John McCall54abf7d2009-11-04 02:18:39 +00005141 // Delay if we're currently parsing a declaration.
John McCalleee1d542011-02-14 07:13:47 +00005142 if (DelayedDiagnostics.shouldDelayDiagnostics()) {
Fariborz Jahanianb0a66152012-03-02 21:50:02 +00005143 DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
5144 UnknownObjCClass,
Fariborz Jahanianfd090882012-09-21 20:46:37 +00005145 ObjCProperty,
Fariborz Jahanianb0a66152012-03-02 21:50:02 +00005146 Message));
John McCall54abf7d2009-11-04 02:18:39 +00005147 return;
5148 }
5149
5150 // Otherwise, don't warn if our current context is deprecated.
Argyrios Kyrtzidis3a387442011-10-06 23:23:20 +00005151 if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
John McCall54abf7d2009-11-04 02:18:39 +00005152 return;
Fariborz Jahanianfd090882012-09-21 20:46:37 +00005153 DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass, ObjCProperty);
John McCall54abf7d2009-11-04 02:18:39 +00005154}