SemaDeclAttr.cpp revision 5b160927672440076aa53c31d84149f70fd8d40e
1//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file implements decl-related attribute processing.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Sema.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/DeclObjC.h"
17#include "clang/AST/Expr.h"
18#include "clang/Basic/TargetInfo.h"
19#include "clang/Parse/DeclSpec.h"
20#include <llvm/ADT/StringExtras.h>
21using namespace clang;
22
23//===----------------------------------------------------------------------===//
24//  Helper functions
25//===----------------------------------------------------------------------===//
26
27static const FunctionType *getFunctionType(Decl *d, bool blocksToo = true) {
28  QualType Ty;
29  if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
30    Ty = decl->getType();
31  else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
32    Ty = decl->getType();
33  else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
34    Ty = decl->getUnderlyingType();
35  else
36    return 0;
37
38  if (Ty->isFunctionPointerType())
39    Ty = Ty->getAsPointerType()->getPointeeType();
40  else if (blocksToo && Ty->isBlockPointerType())
41    Ty = Ty->getAsBlockPointerType()->getPointeeType();
42
43  return Ty->getAsFunctionType();
44}
45
46// FIXME: We should provide an abstraction around a method or function
47// to provide the following bits of information.
48
49/// isFunctionOrMethod - Return true if the given decl has function
50/// type (function or function-typed variable) or an Objective-C
51/// method.
52static bool isFunctionOrMethod(Decl *d) {
53  return getFunctionType(d, false) || isa<ObjCMethodDecl>(d);
54}
55
56/// isFunctionOrMethodOrBlock - Return true if the given decl has function
57/// type (function or function-typed variable) or an Objective-C
58/// method or a block.
59static bool isFunctionOrMethodOrBlock(Decl *d) {
60  if (isFunctionOrMethod(d))
61    return true;
62  // check for block is more involved.
63  if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
64    QualType Ty = V->getType();
65    return Ty->isBlockPointerType();
66  }
67  return isa<BlockDecl>(d);
68}
69
70/// hasFunctionProto - Return true if the given decl has a argument
71/// information. This decl should have already passed
72/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
73static bool hasFunctionProto(Decl *d) {
74  if (const FunctionType *FnTy = getFunctionType(d))
75    return isa<FunctionProtoType>(FnTy);
76  else {
77    assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d));
78    return true;
79  }
80}
81
82/// getFunctionOrMethodNumArgs - Return number of function or method
83/// arguments. It is an error to call this on a K&R function (use
84/// hasFunctionProto first).
85static unsigned getFunctionOrMethodNumArgs(Decl *d) {
86  if (const FunctionType *FnTy = getFunctionType(d))
87    return cast<FunctionProtoType>(FnTy)->getNumArgs();
88  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
89    return BD->getNumParams();
90  return cast<ObjCMethodDecl>(d)->param_size();
91}
92
93static QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) {
94  if (const FunctionType *FnTy = getFunctionType(d))
95    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
96  if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
97    return BD->getParamDecl(Idx)->getType();
98
99  return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
100}
101
102static QualType getFunctionOrMethodResultType(Decl *d) {
103  if (const FunctionType *FnTy = getFunctionType(d))
104    return cast<FunctionProtoType>(FnTy)->getResultType();
105  return cast<ObjCMethodDecl>(d)->getResultType();
106}
107
108static bool isFunctionOrMethodVariadic(Decl *d) {
109  if (const FunctionType *FnTy = getFunctionType(d)) {
110    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
111    return proto->isVariadic();
112  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
113    return BD->IsVariadic();
114  else {
115    return cast<ObjCMethodDecl>(d)->isVariadic();
116  }
117}
118
119static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
120  const PointerType *PT = T->getAsPointerType();
121  if (!PT)
122    return false;
123
124  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType();
125  if (!ClsT)
126    return false;
127
128  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
129
130  // FIXME: Should we walk the chain of classes?
131  return ClsName == &Ctx.Idents.get("NSString") ||
132         ClsName == &Ctx.Idents.get("NSMutableString");
133}
134
135static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
136  const PointerType *PT = T->getAsPointerType();
137  if (!PT)
138    return false;
139
140  const RecordType *RT = PT->getPointeeType()->getAsRecordType();
141  if (!RT)
142    return false;
143
144  const RecordDecl *RD = RT->getDecl();
145  if (RD->getTagKind() != TagDecl::TK_struct)
146    return false;
147
148  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
149}
150
151//===----------------------------------------------------------------------===//
152// Attribute Implementations
153//===----------------------------------------------------------------------===//
154
155// FIXME: All this manual attribute parsing code is gross. At the
156// least add some helper functions to check most argument patterns (#
157// and types of args).
158
159static void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
160                                    Sema &S) {
161  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
162  if (tDecl == 0) {
163    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
164    return;
165  }
166
167  QualType curType = tDecl->getUnderlyingType();
168  // check the attribute arguments.
169  if (Attr.getNumArgs() != 1) {
170    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
171    return;
172  }
173  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
174  llvm::APSInt vecSize(32);
175  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
176    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
177      << "ext_vector_type" << sizeExpr->getSourceRange();
178    return;
179  }
180  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
181  // in conjunction with complex types (pointers, arrays, functions, etc.).
182  if (!curType->isIntegerType() && !curType->isRealFloatingType()) {
183    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << curType;
184    return;
185  }
186  // unlike gcc's vector_size attribute, the size is specified as the
187  // number of elements, not the number of bytes.
188  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
189
190  if (vectorSize == 0) {
191    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
192      << sizeExpr->getSourceRange();
193    return;
194  }
195  // Instantiate/Install the vector type, the number of elements is > 0.
196  tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize));
197  // Remember this typedef decl, we will need it later for diagnostics.
198  S.ExtVectorDecls.push_back(tDecl);
199}
200
201
202/// HandleVectorSizeAttribute - this attribute is only applicable to
203/// integral and float scalars, although arrays, pointers, and function
204/// return values are allowed in conjunction with this construct. Aggregates
205/// with this attribute are invalid, even if they are of the same size as a
206/// corresponding scalar.
207/// The raw attribute should contain precisely 1 argument, the vector size
208/// for the variable, measured in bytes. If curType and rawAttr are well
209/// formed, this routine will return a new vector type.
210static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
211  QualType CurType;
212  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
213    CurType = VD->getType();
214  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
215    CurType = TD->getUnderlyingType();
216  else {
217    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
218      << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc());
219    return;
220  }
221
222  // Check the attribute arugments.
223  if (Attr.getNumArgs() != 1) {
224    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
225    return;
226  }
227  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
228  llvm::APSInt vecSize(32);
229  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
230    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
231      << "vector_size" << sizeExpr->getSourceRange();
232    return;
233  }
234  // navigate to the base type - we need to provide for vector pointers,
235  // vector arrays, and functions returning vectors.
236  if (CurType->isPointerType() || CurType->isArrayType() ||
237      CurType->isFunctionType()) {
238    S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType;
239    return;
240    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
241     do {
242     if (PointerType *PT = dyn_cast<PointerType>(canonType))
243     canonType = PT->getPointeeType().getTypePtr();
244     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
245     canonType = AT->getElementType().getTypePtr();
246     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
247     canonType = FT->getResultType().getTypePtr();
248     } while (canonType->isPointerType() || canonType->isArrayType() ||
249     canonType->isFunctionType());
250     */
251  }
252  // the base type must be integer or float, and can't already be a vector.
253  if (CurType->isVectorType() ||
254      (!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
255    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
256    return;
257  }
258  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
259  // vecSize is specified in bytes - convert to bits.
260  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
261
262  // the vector size needs to be an integral multiple of the type size.
263  if (vectorSize % typeSize) {
264    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
265      << sizeExpr->getSourceRange();
266    return;
267  }
268  if (vectorSize == 0) {
269    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
270      << sizeExpr->getSourceRange();
271    return;
272  }
273
274  // Success! Instantiate the vector type, the number of elements is > 0, and
275  // not required to be a power of 2, unlike GCC.
276  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
277
278  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
279    VD->setType(CurType);
280  else
281    cast<TypedefDecl>(D)->setUnderlyingType(CurType);
282}
283
284static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
285  // check the attribute arguments.
286  if (Attr.getNumArgs() > 0) {
287    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
288    return;
289  }
290
291  if (TagDecl *TD = dyn_cast<TagDecl>(d))
292    TD->addAttr(::new (S.Context) PackedAttr(1));
293  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
294    // If the alignment is less than or equal to 8 bits, the packed attribute
295    // has no effect.
296    if (!FD->getType()->isIncompleteType() &&
297        S.Context.getTypeAlign(FD->getType()) <= 8)
298      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
299        << Attr.getName() << FD->getType();
300    else
301      FD->addAttr(::new (S.Context) PackedAttr(1));
302  } else
303    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
304}
305
306static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
307  // check the attribute arguments.
308  if (Attr.getNumArgs() > 0) {
309    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
310    return;
311  }
312
313  // The IBOutlet attribute only applies to instance variables of Objective-C
314  // classes.
315  if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))
316    d->addAttr(::new (S.Context) IBOutletAttr());
317  else
318    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet);
319}
320
321static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
322  // GCC ignores the nonnull attribute on K&R style function
323  // prototypes, so we ignore it as well
324  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
325    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
326      << Attr.getName() << 0 /*function*/;
327    return;
328  }
329
330  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
331
332  // The nonnull attribute only applies to pointers.
333  llvm::SmallVector<unsigned, 10> NonNullArgs;
334
335  for (AttributeList::arg_iterator I=Attr.arg_begin(),
336                                   E=Attr.arg_end(); I!=E; ++I) {
337
338
339    // The argument must be an integer constant expression.
340    Expr *Ex = static_cast<Expr *>(*I);
341    llvm::APSInt ArgNum(32);
342    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
343      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
344        << "nonnull" << Ex->getSourceRange();
345      return;
346    }
347
348    unsigned x = (unsigned) ArgNum.getZExtValue();
349
350    if (x < 1 || x > NumArgs) {
351      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
352       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
353      return;
354    }
355
356    --x;
357
358    // Is the function argument a pointer type?
359    QualType T = getFunctionOrMethodArgType(d, x);
360    if (!T->isPointerType() && !T->isBlockPointerType()) {
361      // FIXME: Should also highlight argument in decl.
362      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only)
363        << "nonnull" << Ex->getSourceRange();
364      continue;
365    }
366
367    NonNullArgs.push_back(x);
368  }
369
370  // If no arguments were specified to __attribute__((nonnull)) then all
371  // pointer arguments have a nonnull attribute.
372  if (NonNullArgs.empty()) {
373    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
374      QualType T = getFunctionOrMethodArgType(d, I);
375      if (T->isPointerType() || T->isBlockPointerType())
376        NonNullArgs.push_back(I);
377    }
378
379    if (NonNullArgs.empty()) {
380      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
381      return;
382    }
383  }
384
385  unsigned* start = &NonNullArgs[0];
386  unsigned size = NonNullArgs.size();
387  std::sort(start, start + size);
388  d->addAttr(::new (S.Context) NonNullAttr(start, size));
389}
390
391static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
392  // check the attribute arguments.
393  if (Attr.getNumArgs() != 1) {
394    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
395    return;
396  }
397
398  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
399  Arg = Arg->IgnoreParenCasts();
400  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
401
402  if (Str == 0 || Str->isWide()) {
403    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
404      << "alias" << 1;
405    return;
406  }
407
408  const char *Alias = Str->getStrData();
409  unsigned AliasLen = Str->getByteLength();
410
411  // FIXME: check if target symbol exists in current file
412
413  d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
414}
415
416static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
417                                   Sema &S) {
418  // check the attribute arguments.
419  if (Attr.getNumArgs() != 0) {
420    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
421    return;
422  }
423
424  if (!isa<FunctionDecl>(d)) {
425    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
426    << Attr.getName() << 0 /*function*/;
427    return;
428  }
429
430  d->addAttr(::new (S.Context) AlwaysInlineAttr());
431}
432
433static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
434                                     Sema &S) {
435  // check the attribute arguments.
436  if (Attr.getNumArgs() != 0) {
437    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
438    return false;
439  }
440
441  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
442    ValueDecl *VD = dyn_cast<ValueDecl>(d);
443    if (VD == 0 || !VD->getType()->isBlockPointerType()) {
444      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
445        << Attr.getName() << 0 /*function*/;
446      return false;
447    }
448  }
449
450  return true;
451}
452
453static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
454  if (HandleCommonNoReturnAttr(d, Attr, S))
455    d->addAttr(::new (S.Context) NoReturnAttr());
456}
457
458static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
459                                       Sema &S) {
460  if (HandleCommonNoReturnAttr(d, Attr, S))
461    d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
462}
463
464static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
465  // check the attribute arguments.
466  if (Attr.getNumArgs() != 0) {
467    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
468    return;
469  }
470
471  if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) {
472    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
473      << Attr.getName() << 2 /*variable and function*/;
474    return;
475  }
476
477  d->addAttr(::new (S.Context) UnusedAttr());
478}
479
480static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
481  // check the attribute arguments.
482  if (Attr.getNumArgs() != 0) {
483    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
484    return;
485  }
486
487  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
488    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
489      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
490      return;
491    }
492  } else if (!isFunctionOrMethod(d)) {
493    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
494      << Attr.getName() << 2 /*variable and function*/;
495    return;
496  }
497
498  d->addAttr(::new (S.Context) UsedAttr());
499}
500
501static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
502  // check the attribute arguments.
503  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
504    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
505      << "0 or 1";
506    return;
507  }
508
509  int priority = 65535; // FIXME: Do not hardcode such constants.
510  if (Attr.getNumArgs() > 0) {
511    Expr *E = static_cast<Expr *>(Attr.getArg(0));
512    llvm::APSInt Idx(32);
513    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
514      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
515        << "constructor" << 1 << E->getSourceRange();
516      return;
517    }
518    priority = Idx.getZExtValue();
519  }
520
521  if (!isa<FunctionDecl>(d)) {
522    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
523      << Attr.getName() << 0 /*function*/;
524    return;
525  }
526
527  d->addAttr(::new (S.Context) ConstructorAttr(priority));
528}
529
530static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
531  // check the attribute arguments.
532  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
533    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
534       << "0 or 1";
535    return;
536  }
537
538  int priority = 65535; // FIXME: Do not hardcode such constants.
539  if (Attr.getNumArgs() > 0) {
540    Expr *E = static_cast<Expr *>(Attr.getArg(0));
541    llvm::APSInt Idx(32);
542    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
543      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
544        << "destructor" << 1 << E->getSourceRange();
545      return;
546    }
547    priority = Idx.getZExtValue();
548  }
549
550  if (!isa<FunctionDecl>(d)) {
551    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
552      << Attr.getName() << 0 /*function*/;
553    return;
554  }
555
556  d->addAttr(::new (S.Context) DestructorAttr(priority));
557}
558
559static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
560  // check the attribute arguments.
561  if (Attr.getNumArgs() != 0) {
562    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
563    return;
564  }
565
566  d->addAttr(::new (S.Context) DeprecatedAttr());
567}
568
569static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
570  // check the attribute arguments.
571  if (Attr.getNumArgs() != 0) {
572    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
573    return;
574  }
575
576  d->addAttr(::new (S.Context) UnavailableAttr());
577}
578
579static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
580  // check the attribute arguments.
581  if (Attr.getNumArgs() != 1) {
582    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
583    return;
584  }
585
586  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
587  Arg = Arg->IgnoreParenCasts();
588  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
589
590  if (Str == 0 || Str->isWide()) {
591    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
592      << "visibility" << 1;
593    return;
594  }
595
596  const char *TypeStr = Str->getStrData();
597  unsigned TypeLen = Str->getByteLength();
598  VisibilityAttr::VisibilityTypes type;
599
600  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
601    type = VisibilityAttr::DefaultVisibility;
602  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
603    type = VisibilityAttr::HiddenVisibility;
604  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
605    type = VisibilityAttr::HiddenVisibility; // FIXME
606  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
607    type = VisibilityAttr::ProtectedVisibility;
608  else {
609    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
610    return;
611  }
612
613  d->addAttr(::new (S.Context) VisibilityAttr(type));
614}
615
616static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
617                                    Sema &S) {
618  if (Attr.getNumArgs() != 0) {
619    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
620    return;
621  }
622
623  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
624  if (OCI == 0) {
625    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
626    return;
627  }
628
629  D->addAttr(::new (S.Context) ObjCExceptionAttr());
630}
631
632static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
633  if (Attr.getNumArgs() != 0) {
634    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
635    return;
636  }
637  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
638    QualType T = TD->getUnderlyingType();
639    if (!T->isPointerType() ||
640        !T->getAsPointerType()->getPointeeType()->isRecordType()) {
641      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
642      return;
643    }
644  }
645  D->addAttr(::new (S.Context) ObjCNSObjectAttr());
646}
647
648static void
649HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
650  if (Attr.getNumArgs() != 0) {
651    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
652    return;
653  }
654
655  if (!isa<FunctionDecl>(D)) {
656    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
657    return;
658  }
659
660  D->addAttr(::new (S.Context) OverloadableAttr());
661}
662
663static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
664  if (!Attr.getParameterName()) {
665    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
666      << "blocks" << 1;
667    return;
668  }
669
670  if (Attr.getNumArgs() != 0) {
671    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
672    return;
673  }
674
675  BlocksAttr::BlocksAttrTypes type;
676  if (Attr.getParameterName()->isStr("byref"))
677    type = BlocksAttr::ByRef;
678  else {
679    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
680      << "blocks" << Attr.getParameterName();
681    return;
682  }
683
684  d->addAttr(::new (S.Context) BlocksAttr(type));
685}
686
687static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
688  // check the attribute arguments.
689  if (Attr.getNumArgs() > 2) {
690    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
691      << "0, 1 or 2";
692    return;
693  }
694
695  int sentinel = 0;
696  if (Attr.getNumArgs() > 0) {
697    Expr *E = static_cast<Expr *>(Attr.getArg(0));
698    llvm::APSInt Idx(32);
699    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
700      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
701       << "sentinel" << 1 << E->getSourceRange();
702      return;
703    }
704    sentinel = Idx.getZExtValue();
705
706    if (sentinel < 0) {
707      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
708        << E->getSourceRange();
709      return;
710    }
711  }
712
713  int nullPos = 0;
714  if (Attr.getNumArgs() > 1) {
715    Expr *E = static_cast<Expr *>(Attr.getArg(1));
716    llvm::APSInt Idx(32);
717    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
718      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
719        << "sentinel" << 2 << E->getSourceRange();
720      return;
721    }
722    nullPos = Idx.getZExtValue();
723
724    if (nullPos > 1 || nullPos < 0) {
725      // FIXME: This error message could be improved, it would be nice
726      // to say what the bounds actually are.
727      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
728        << E->getSourceRange();
729      return;
730    }
731  }
732
733  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
734    const FunctionType *FT = FD->getType()->getAsFunctionType();
735    assert(FT && "FunctionDecl has non-function type?");
736
737    if (isa<FunctionNoProtoType>(FT)) {
738      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
739      return;
740    }
741
742    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
743      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
744      return;
745    }
746  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
747    if (!MD->isVariadic()) {
748      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
749      return;
750    }
751  } else if (isa<BlockDecl>(d)) {
752    // Note! BlockDecl is typeless. Variadic diagnostics
753    // will be issued by the caller.
754    ;
755  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
756    QualType Ty = V->getType();
757    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
758      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
759        : Ty->getAsBlockPointerType()->getPointeeType()->getAsFunctionType();
760      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
761        int m = Ty->isFunctionPointerType() ? 0 : 1;
762        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
763        return;
764      }
765    }
766    else {
767      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
768      << Attr.getName() << 6 /*function, method or block */;
769      return;
770    }
771  } else {
772    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
773      << Attr.getName() << 6 /*function, method or block */;
774    return;
775  }
776  d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
777}
778
779static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
780  // check the attribute arguments.
781  if (Attr.getNumArgs() != 0) {
782    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
783    return;
784  }
785
786  // TODO: could also be applied to methods?
787  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
788  if (!Fn) {
789    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
790      << Attr.getName() << 0 /*function*/;
791    return;
792  }
793
794  Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
795}
796
797static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
798  // check the attribute arguments.
799  if (Attr.getNumArgs() != 0) {
800    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
801    return;
802  }
803
804  // TODO: could also be applied to methods?
805  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
806    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
807      << Attr.getName() << 2 /*variable and function*/;
808    return;
809  }
810
811  D->addAttr(::new (S.Context) WeakAttr());
812}
813
814static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
815  // check the attribute arguments.
816  if (Attr.getNumArgs() != 0) {
817    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
818    return;
819  }
820
821  // weak_import only applies to variable & function declarations.
822  bool isDef = false;
823  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
824    isDef = (!VD->hasExternalStorage() || VD->getInit());
825  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
826    isDef = FD->getBody(S.Context);
827  } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
828    // We ignore weak import on properties and methods
829    return;
830  } else {
831    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
832    << Attr.getName() << 2 /*variable and function*/;
833    return;
834  }
835
836  // Merge should handle any subsequent violations.
837  if (isDef) {
838    S.Diag(Attr.getLoc(),
839           diag::warn_attribute_weak_import_invalid_on_definition)
840      << "weak_import" << 2 /*variable and function*/;
841    return;
842  }
843
844  D->addAttr(::new (S.Context) WeakImportAttr());
845}
846
847static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
848  // check the attribute arguments.
849  if (Attr.getNumArgs() != 0) {
850    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
851    return;
852  }
853
854  // Attribute can be applied only to functions or variables.
855  if (isa<VarDecl>(D)) {
856    D->addAttr(::new (S.Context) DLLImportAttr());
857    return;
858  }
859
860  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
861  if (!FD) {
862    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
863      << Attr.getName() << 2 /*variable and function*/;
864    return;
865  }
866
867  // Currently, the dllimport attribute is ignored for inlined functions.
868  // Warning is emitted.
869  if (FD->isInline()) {
870    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
871    return;
872  }
873
874  // The attribute is also overridden by a subsequent declaration as dllexport.
875  // Warning is emitted.
876  for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
877       nextAttr = nextAttr->getNext()) {
878    if (nextAttr->getKind() == AttributeList::AT_dllexport) {
879      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
880      return;
881    }
882  }
883
884  if (D->getAttr<DLLExportAttr>()) {
885    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
886    return;
887  }
888
889  D->addAttr(::new (S.Context) DLLImportAttr());
890}
891
892static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
893  // check the attribute arguments.
894  if (Attr.getNumArgs() != 0) {
895    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
896    return;
897  }
898
899  // Attribute can be applied only to functions or variables.
900  if (isa<VarDecl>(D)) {
901    D->addAttr(::new (S.Context) DLLExportAttr());
902    return;
903  }
904
905  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
906  if (!FD) {
907    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
908      << Attr.getName() << 2 /*variable and function*/;
909    return;
910  }
911
912  // Currently, the dllexport attribute is ignored for inlined functions,
913  // unless the -fkeep-inline-functions flag has been used. Warning is emitted;
914  if (FD->isInline()) {
915    // FIXME: ... unless the -fkeep-inline-functions flag has been used.
916    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
917    return;
918  }
919
920  D->addAttr(::new (S.Context) DLLExportAttr());
921}
922
923static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
924  // Attribute has no arguments.
925  if (Attr.getNumArgs() != 1) {
926    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
927    return;
928  }
929
930  // Make sure that there is a string literal as the sections's single
931  // argument.
932  StringLiteral *SE =
933    dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0)));
934  if (!SE) {
935    // FIXME
936    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
937    return;
938  }
939  D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(),
940                                                     SE->getByteLength())));
941}
942
943static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
944  // Attribute has no arguments.
945  if (Attr.getNumArgs() != 0) {
946    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
947    return;
948  }
949
950  // Attribute can be applied only to functions.
951  if (!isa<FunctionDecl>(d)) {
952    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
953      << Attr.getName() << 0 /*function*/;
954    return;
955  }
956
957  // stdcall and fastcall attributes are mutually incompatible.
958  if (d->getAttr<FastCallAttr>()) {
959    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
960      << "stdcall" << "fastcall";
961    return;
962  }
963
964  d->addAttr(::new (S.Context) StdCallAttr());
965}
966
967static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
968  // Attribute has no arguments.
969  if (Attr.getNumArgs() != 0) {
970    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
971    return;
972  }
973
974  if (!isa<FunctionDecl>(d)) {
975    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
976      << Attr.getName() << 0 /*function*/;
977    return;
978  }
979
980  // stdcall and fastcall attributes are mutually incompatible.
981  if (d->getAttr<StdCallAttr>()) {
982    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
983      << "fastcall" << "stdcall";
984    return;
985  }
986
987  d->addAttr(::new (S.Context) FastCallAttr());
988}
989
990static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
991  // check the attribute arguments.
992  if (Attr.getNumArgs() != 0) {
993    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
994    return;
995  }
996
997  d->addAttr(::new (S.Context) NoThrowAttr());
998}
999
1000static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1001  // check the attribute arguments.
1002  if (Attr.getNumArgs() != 0) {
1003    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1004    return;
1005  }
1006
1007  d->addAttr(::new (S.Context) ConstAttr());
1008}
1009
1010static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1011  // check the attribute arguments.
1012  if (Attr.getNumArgs() != 0) {
1013    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1014    return;
1015  }
1016
1017  d->addAttr(::new (S.Context) PureAttr());
1018}
1019
1020static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1021  // Match gcc which ignores cleanup attrs when compiling C++.
1022  if (S.getLangOptions().CPlusPlus)
1023    return;
1024
1025  if (!Attr.getParameterName()) {
1026    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1027    return;
1028  }
1029
1030  if (Attr.getNumArgs() != 0) {
1031    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1032    return;
1033  }
1034
1035  VarDecl *VD = dyn_cast<VarDecl>(d);
1036
1037  if (!VD || !VD->hasLocalStorage()) {
1038    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1039    return;
1040  }
1041
1042  // Look up the function
1043  NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
1044                                        Sema::LookupOrdinaryName);
1045  if (!CleanupDecl) {
1046    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1047      Attr.getParameterName();
1048    return;
1049  }
1050
1051  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1052  if (!FD) {
1053    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
1054      Attr.getParameterName();
1055    return;
1056  }
1057
1058  if (FD->getNumParams() != 1) {
1059    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
1060      Attr.getParameterName();
1061    return;
1062  }
1063
1064  // We're currently more strict than GCC about what function types we accept.
1065  // If this ever proves to be a problem it should be easy to fix.
1066  QualType Ty = S.Context.getPointerType(VD->getType());
1067  QualType ParamTy = FD->getParamDecl(0)->getType();
1068  if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
1069    S.Diag(Attr.getLoc(),
1070           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
1071      Attr.getParameterName() << ParamTy << Ty;
1072    return;
1073  }
1074
1075  d->addAttr(::new (S.Context) CleanupAttr(FD));
1076}
1077
1078/// Handle __attribute__((format_arg((idx)))) attribute
1079/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1080static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1081  if (Attr.getNumArgs() != 1) {
1082    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1083    return;
1084  }
1085  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
1086    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1087    << Attr.getName() << 0 /*function*/;
1088    return;
1089  }
1090  // FIXME: in C++ the implicit 'this' function parameter also counts.
1091  // this is needed in order to be compatible with GCC
1092  // the index must start with 1.
1093  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
1094  unsigned FirstIdx = 1;
1095  // checks for the 2nd argument
1096  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1097  llvm::APSInt Idx(32);
1098  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1099    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1100    << "format" << 2 << IdxExpr->getSourceRange();
1101    return;
1102  }
1103
1104  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1105    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1106    << "format" << 2 << IdxExpr->getSourceRange();
1107    return;
1108  }
1109
1110  unsigned ArgIdx = Idx.getZExtValue() - 1;
1111
1112  // make sure the format string is really a string
1113  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1114
1115  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
1116  if (not_nsstring_type &&
1117      !isCFStringType(Ty, S.Context) &&
1118      (!Ty->isPointerType() ||
1119       !Ty->getAsPointerType()->getPointeeType()->isCharType())) {
1120    // FIXME: Should highlight the actual expression that has the wrong type.
1121    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1122    << (not_nsstring_type ? "a string type" : "an NSString")
1123       << IdxExpr->getSourceRange();
1124    return;
1125  }
1126  Ty = getFunctionOrMethodResultType(d);
1127  if (!isNSStringType(Ty, S.Context) &&
1128      !isCFStringType(Ty, S.Context) &&
1129      (!Ty->isPointerType() ||
1130       !Ty->getAsPointerType()->getPointeeType()->isCharType())) {
1131    // FIXME: Should highlight the actual expression that has the wrong type.
1132    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1133    << (not_nsstring_type ? "string type" : "NSString")
1134       << IdxExpr->getSourceRange();
1135    return;
1136  }
1137
1138  d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
1139}
1140
1141/// Handle __attribute__((format(type,idx,firstarg))) attributes
1142/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1143static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1144
1145  if (!Attr.getParameterName()) {
1146    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1147      << "format" << 1;
1148    return;
1149  }
1150
1151  if (Attr.getNumArgs() != 2) {
1152    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
1153    return;
1154  }
1155
1156  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1157    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1158      << Attr.getName() << 0 /*function*/;
1159    return;
1160  }
1161
1162  // FIXME: in C++ the implicit 'this' function parameter also counts.
1163  // this is needed in order to be compatible with GCC
1164  // the index must start in 1 and the limit is numargs+1
1165  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
1166  unsigned FirstIdx = 1;
1167
1168  const char *Format = Attr.getParameterName()->getName();
1169  unsigned FormatLen = Attr.getParameterName()->getLength();
1170
1171  // Normalize the argument, __foo__ becomes foo.
1172  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
1173      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
1174    Format += 2;
1175    FormatLen -= 4;
1176  }
1177
1178  bool Supported = false;
1179  bool is_NSString = false;
1180  bool is_strftime = false;
1181  bool is_CFString = false;
1182
1183  switch (FormatLen) {
1184  default: break;
1185  case 5: Supported = !memcmp(Format, "scanf", 5); break;
1186  case 6: Supported = !memcmp(Format, "printf", 6); break;
1187  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
1188  case 8:
1189    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
1190                (is_NSString = !memcmp(Format, "NSString", 8)) ||
1191                (is_CFString = !memcmp(Format, "CFString", 8));
1192    break;
1193  }
1194
1195  if (!Supported) {
1196    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1197      << "format" << Attr.getParameterName()->getName();
1198    return;
1199  }
1200
1201  // checks for the 2nd argument
1202  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1203  llvm::APSInt Idx(32);
1204  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1205    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1206      << "format" << 2 << IdxExpr->getSourceRange();
1207    return;
1208  }
1209
1210  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1211    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1212      << "format" << 2 << IdxExpr->getSourceRange();
1213    return;
1214  }
1215
1216  // FIXME: Do we need to bounds check?
1217  unsigned ArgIdx = Idx.getZExtValue() - 1;
1218
1219  // make sure the format string is really a string
1220  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1221
1222  if (is_CFString) {
1223    if (!isCFStringType(Ty, S.Context)) {
1224      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1225        << "a CFString" << IdxExpr->getSourceRange();
1226      return;
1227    }
1228  } else if (is_NSString) {
1229    // FIXME: do we need to check if the type is NSString*?  What are the
1230    // semantics?
1231    if (!isNSStringType(Ty, S.Context)) {
1232      // FIXME: Should highlight the actual expression that has the wrong type.
1233      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1234        << "an NSString" << IdxExpr->getSourceRange();
1235      return;
1236    }
1237  } else if (!Ty->isPointerType() ||
1238             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
1239    // FIXME: Should highlight the actual expression that has the wrong type.
1240    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1241      << "a string type" << IdxExpr->getSourceRange();
1242    return;
1243  }
1244
1245  // check the 3rd argument
1246  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1247  llvm::APSInt FirstArg(32);
1248  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1249    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1250      << "format" << 3 << FirstArgExpr->getSourceRange();
1251    return;
1252  }
1253
1254  // check if the function is variadic if the 3rd argument non-zero
1255  if (FirstArg != 0) {
1256    if (isFunctionOrMethodVariadic(d)) {
1257      ++NumArgs; // +1 for ...
1258    } else {
1259      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
1260      return;
1261    }
1262  }
1263
1264  // strftime requires FirstArg to be 0 because it doesn't read from any
1265  // variable the input is just the current time + the format string.
1266  if (is_strftime) {
1267    if (FirstArg != 0) {
1268      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1269        << FirstArgExpr->getSourceRange();
1270      return;
1271    }
1272  // if 0 it disables parameter checking (to use with e.g. va_list)
1273  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1274    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1275      << "format" << 3 << FirstArgExpr->getSourceRange();
1276    return;
1277  }
1278
1279  d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen),
1280                            Idx.getZExtValue(), FirstArg.getZExtValue()));
1281}
1282
1283static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
1284                                       Sema &S) {
1285  // check the attribute arguments.
1286  if (Attr.getNumArgs() != 0) {
1287    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1288    return;
1289  }
1290
1291  // Try to find the underlying union declaration.
1292  RecordDecl *RD = 0;
1293  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
1294  if (TD && TD->getUnderlyingType()->isUnionType())
1295    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
1296  else
1297    RD = dyn_cast<RecordDecl>(d);
1298
1299  if (!RD || !RD->isUnion()) {
1300    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1301      << Attr.getName() << 1 /*union*/;
1302    return;
1303  }
1304
1305  if (!RD->isDefinition()) {
1306    S.Diag(Attr.getLoc(),
1307        diag::warn_transparent_union_attribute_not_definition);
1308    return;
1309  }
1310
1311  RecordDecl::field_iterator Field = RD->field_begin(S.Context),
1312                          FieldEnd = RD->field_end(S.Context);
1313  if (Field == FieldEnd) {
1314    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
1315    return;
1316  }
1317
1318  FieldDecl *FirstField = *Field;
1319  QualType FirstType = FirstField->getType();
1320  if (FirstType->isFloatingType() || FirstType->isVectorType()) {
1321    S.Diag(FirstField->getLocation(),
1322           diag::warn_transparent_union_attribute_floating);
1323    return;
1324  }
1325
1326  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
1327  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
1328  for (; Field != FieldEnd; ++Field) {
1329    QualType FieldType = Field->getType();
1330    if (S.Context.getTypeSize(FieldType) != FirstSize ||
1331        S.Context.getTypeAlign(FieldType) != FirstAlign) {
1332      // Warn if we drop the attribute.
1333      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1334      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
1335                                 : S.Context.getTypeAlign(FieldType);
1336      S.Diag(Field->getLocation(),
1337          diag::warn_transparent_union_attribute_field_size_align)
1338        << isSize << Field->getDeclName() << FieldBits;
1339      unsigned FirstBits = isSize? FirstSize : FirstAlign;
1340      S.Diag(FirstField->getLocation(),
1341             diag::note_transparent_union_first_field_size_align)
1342        << isSize << FirstBits;
1343      return;
1344    }
1345  }
1346
1347  RD->addAttr(::new (S.Context) TransparentUnionAttr());
1348}
1349
1350static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1351  // check the attribute arguments.
1352  if (Attr.getNumArgs() != 1) {
1353    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1354    return;
1355  }
1356  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
1357  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
1358
1359  // Make sure that there is a string literal as the annotation's single
1360  // argument.
1361  if (!SE) {
1362    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
1363    return;
1364  }
1365  d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
1366                                                        SE->getByteLength())));
1367}
1368
1369static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1370  // check the attribute arguments.
1371  if (Attr.getNumArgs() > 1) {
1372    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1373    return;
1374  }
1375
1376  unsigned Align = 0;
1377  if (Attr.getNumArgs() == 0) {
1378    // FIXME: This should be the target specific maximum alignment.
1379    // (For now we just use 128 bits which is the maximum on X86).
1380    Align = 128;
1381    d->addAttr(::new (S.Context) AlignedAttr(Align));
1382    return;
1383  }
1384
1385  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
1386  llvm::APSInt Alignment(32);
1387  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1388    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1389      << "aligned" << alignmentExpr->getSourceRange();
1390    return;
1391  }
1392  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
1393    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
1394      << alignmentExpr->getSourceRange();
1395    return;
1396  }
1397
1398  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
1399}
1400
1401/// HandleModeAttr - This attribute modifies the width of a decl with
1402/// primitive type.
1403///
1404/// Despite what would be logical, the mode attribute is a decl attribute,
1405/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
1406/// 'G' be HImode, not an intermediate pointer.
1407///
1408static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1409  // This attribute isn't documented, but glibc uses it.  It changes
1410  // the width of an int or unsigned int to the specified size.
1411
1412  // Check that there aren't any arguments
1413  if (Attr.getNumArgs() != 0) {
1414    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1415    return;
1416  }
1417
1418  IdentifierInfo *Name = Attr.getParameterName();
1419  if (!Name) {
1420    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1421    return;
1422  }
1423  const char *Str = Name->getName();
1424  unsigned Len = Name->getLength();
1425
1426  // Normalize the attribute name, __foo__ becomes foo.
1427  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
1428      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
1429    Str += 2;
1430    Len -= 4;
1431  }
1432
1433  unsigned DestWidth = 0;
1434  bool IntegerMode = true;
1435  bool ComplexMode = false;
1436  switch (Len) {
1437  case 2:
1438    switch (Str[0]) {
1439    case 'Q': DestWidth = 8; break;
1440    case 'H': DestWidth = 16; break;
1441    case 'S': DestWidth = 32; break;
1442    case 'D': DestWidth = 64; break;
1443    case 'X': DestWidth = 96; break;
1444    case 'T': DestWidth = 128; break;
1445    }
1446    if (Str[1] == 'F') {
1447      IntegerMode = false;
1448    } else if (Str[1] == 'C') {
1449      IntegerMode = false;
1450      ComplexMode = true;
1451    } else if (Str[1] != 'I') {
1452      DestWidth = 0;
1453    }
1454    break;
1455  case 4:
1456    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1457    // pointer on PIC16 and other embedded platforms.
1458    if (!memcmp(Str, "word", 4))
1459      DestWidth = S.Context.Target.getPointerWidth(0);
1460    if (!memcmp(Str, "byte", 4))
1461      DestWidth = S.Context.Target.getCharWidth();
1462    break;
1463  case 7:
1464    if (!memcmp(Str, "pointer", 7))
1465      DestWidth = S.Context.Target.getPointerWidth(0);
1466    break;
1467  }
1468
1469  QualType OldTy;
1470  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1471    OldTy = TD->getUnderlyingType();
1472  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1473    OldTy = VD->getType();
1474  else {
1475    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1476      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1477    return;
1478  }
1479
1480  if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType())
1481    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
1482  else if (IntegerMode) {
1483    if (!OldTy->isIntegralType())
1484      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1485  } else if (ComplexMode) {
1486    if (!OldTy->isComplexType())
1487      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1488  } else {
1489    if (!OldTy->isFloatingType())
1490      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1491  }
1492
1493  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
1494  // and friends, at least with glibc.
1495  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
1496  // width on unusual platforms.
1497  // FIXME: Make sure floating-point mappings are accurate
1498  // FIXME: Support XF and TF types
1499  QualType NewTy;
1500  switch (DestWidth) {
1501  case 0:
1502    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1503    return;
1504  default:
1505    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1506    return;
1507  case 8:
1508    if (!IntegerMode) {
1509      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1510      return;
1511    }
1512    if (OldTy->isSignedIntegerType())
1513      NewTy = S.Context.SignedCharTy;
1514    else
1515      NewTy = S.Context.UnsignedCharTy;
1516    break;
1517  case 16:
1518    if (!IntegerMode) {
1519      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1520      return;
1521    }
1522    if (OldTy->isSignedIntegerType())
1523      NewTy = S.Context.ShortTy;
1524    else
1525      NewTy = S.Context.UnsignedShortTy;
1526    break;
1527  case 32:
1528    if (!IntegerMode)
1529      NewTy = S.Context.FloatTy;
1530    else if (OldTy->isSignedIntegerType())
1531      NewTy = S.Context.IntTy;
1532    else
1533      NewTy = S.Context.UnsignedIntTy;
1534    break;
1535  case 64:
1536    if (!IntegerMode)
1537      NewTy = S.Context.DoubleTy;
1538    else if (OldTy->isSignedIntegerType())
1539      NewTy = S.Context.LongLongTy;
1540    else
1541      NewTy = S.Context.UnsignedLongLongTy;
1542    break;
1543  case 96:
1544    NewTy = S.Context.LongDoubleTy;
1545    break;
1546  case 128:
1547    if (!IntegerMode) {
1548      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1549      return;
1550    }
1551    NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType());
1552    break;
1553  }
1554
1555  if (ComplexMode) {
1556    NewTy = S.Context.getComplexType(NewTy);
1557  }
1558
1559  // Install the new type.
1560  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1561    TD->setUnderlyingType(NewTy);
1562  else
1563    cast<ValueDecl>(D)->setType(NewTy);
1564}
1565
1566static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1567  // check the attribute arguments.
1568  if (Attr.getNumArgs() > 0) {
1569    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1570    return;
1571  }
1572
1573  if (!isFunctionOrMethod(d)) {
1574    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1575      << Attr.getName() << 0 /*function*/;
1576    return;
1577  }
1578
1579  d->addAttr(::new (S.Context) NodebugAttr());
1580}
1581
1582static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1583  // check the attribute arguments.
1584  if (Attr.getNumArgs() != 0) {
1585    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1586    return;
1587  }
1588
1589  if (!isa<FunctionDecl>(d)) {
1590    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1591    << Attr.getName() << 0 /*function*/;
1592    return;
1593  }
1594
1595  d->addAttr(::new (S.Context) NoinlineAttr());
1596}
1597
1598static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1599  // check the attribute arguments.
1600  if (Attr.getNumArgs() != 0) {
1601    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1602    return;
1603  }
1604
1605  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
1606  if (Fn == 0) {
1607    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1608      << Attr.getName() << 0 /*function*/;
1609    return;
1610  }
1611
1612  if (!Fn->isInline()) {
1613    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
1614    return;
1615  }
1616
1617  d->addAttr(::new (S.Context) GNUInlineAttr());
1618}
1619
1620static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1621  // check the attribute arguments.
1622  if (Attr.getNumArgs() != 1) {
1623    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1624    return;
1625  }
1626
1627  if (!isFunctionOrMethod(d)) {
1628    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1629    << Attr.getName() << 0 /*function*/;
1630    return;
1631  }
1632
1633  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
1634  llvm::APSInt NumParams(32);
1635  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
1636    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1637      << "regparm" << NumParamsExpr->getSourceRange();
1638    return;
1639  }
1640
1641  if (S.Context.Target.getRegParmMax() == 0) {
1642    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
1643      << NumParamsExpr->getSourceRange();
1644    return;
1645  }
1646
1647  if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
1648    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
1649      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
1650    return;
1651  }
1652
1653  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
1654}
1655
1656//===----------------------------------------------------------------------===//
1657// Checker-specific attribute handlers.
1658//===----------------------------------------------------------------------===//
1659
1660static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
1661                                        Sema &S) {
1662
1663  QualType RetTy;
1664
1665  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
1666    RetTy = MD->getResultType();
1667  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
1668    RetTy = FD->getResultType();
1669  else {
1670    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1671        << Attr.getName() << 3 /* function or method */;
1672    return;
1673  }
1674
1675  if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAsPointerType())) {
1676    S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
1677      << Attr.getName();
1678    return;
1679  }
1680
1681  switch (Attr.getKind()) {
1682    default:
1683      assert(0 && "invalid ownership attribute");
1684      return;
1685    case AttributeList::AT_cf_returns_retained:
1686      d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
1687      return;
1688    case AttributeList::AT_ns_returns_retained:
1689      d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
1690      return;
1691  };
1692}
1693
1694//===----------------------------------------------------------------------===//
1695// Top Level Sema Entry Points
1696//===----------------------------------------------------------------------===//
1697
1698/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1699/// the attribute applies to decls.  If the attribute is a type attribute, just
1700/// silently ignore it.
1701static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
1702  switch (Attr.getKind()) {
1703  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1704  case AttributeList::AT_address_space:
1705  case AttributeList::AT_objc_gc:
1706    // Ignore these, these are type attributes, handled by ProcessTypeAttributes.
1707    break;
1708  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
1709  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1710  case AttributeList::AT_always_inline:
1711    HandleAlwaysInlineAttr  (D, Attr, S); break;
1712  case AttributeList::AT_analyzer_noreturn:
1713    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
1714  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
1715  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1716  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
1717  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1718  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
1719  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
1720  case AttributeList::AT_ext_vector_type:
1721    HandleExtVectorTypeAttr(D, Attr, S);
1722    break;
1723  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1724  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
1725  case AttributeList::AT_format_arg:  HandleFormatArgAttr (D, Attr, S); break;
1726  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr(D, Attr, S); break;
1727  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
1728  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
1729  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
1730  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
1731
1732  // Checker-specific.
1733  case AttributeList::AT_ns_returns_retained:
1734  case AttributeList::AT_cf_returns_retained:
1735    HandleNSReturnsRetainedAttr(D, Attr, S); break;
1736
1737  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
1738  case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
1739  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
1740  case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
1741  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
1742  case AttributeList::AT_used:        HandleUsedAttr      (D, Attr, S); break;
1743  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
1744  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
1745  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
1746    break;
1747  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
1748  case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break;
1749  case AttributeList::AT_transparent_union:
1750    HandleTransparentUnionAttr(D, Attr, S);
1751    break;
1752  case AttributeList::AT_objc_exception:
1753    HandleObjCExceptionAttr(D, Attr, S);
1754    break;
1755  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
1756  case AttributeList::AT_nsobject:    HandleObjCNSObject  (D, Attr, S); break;
1757  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1758  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1759  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1760  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1761  case AttributeList::AT_cleanup:     HandleCleanupAttr   (D, Attr, S); break;
1762  case AttributeList::AT_nodebug:     HandleNodebugAttr   (D, Attr, S); break;
1763  case AttributeList::AT_noinline:    HandleNoinlineAttr  (D, Attr, S); break;
1764  case AttributeList::AT_regparm:     HandleRegparmAttr   (D, Attr, S); break;
1765  case AttributeList::IgnoredAttribute:
1766  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
1767    // Just ignore
1768    break;
1769  default:
1770    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1771    break;
1772  }
1773}
1774
1775/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1776/// attribute list to the specified decl, ignoring any type attributes.
1777void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
1778  while (AttrList) {
1779    ProcessDeclAttribute(D, *AttrList, *this);
1780    AttrList = AttrList->getNext();
1781  }
1782}
1783
1784/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
1785/// it, apply them to D.  This is a bit tricky because PD can have attributes
1786/// specified in many different places, and we need to find and apply them all.
1787void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
1788  // Apply decl attributes from the DeclSpec if present.
1789  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
1790    ProcessDeclAttributeList(D, Attrs);
1791
1792  // Walk the declarator structure, applying decl attributes that were in a type
1793  // position to the decl itself.  This handles cases like:
1794  //   int *__attr__(x)** D;
1795  // when X is a decl attribute.
1796  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
1797    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
1798      ProcessDeclAttributeList(D, Attrs);
1799
1800  // Finally, apply any attributes on the decl itself.
1801  if (const AttributeList *Attrs = PD.getAttributes())
1802    ProcessDeclAttributeList(D, Attrs);
1803}
1804