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