SemaDeclAttr.cpp revision 9ccc052637d79c54ca11f9ae6084b32f2c0fc1b8
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) {
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 (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) || 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
1156    //  the semantics?
1157    if (!isNSStringType(Ty, S.Context)) {
1158      // FIXME: Should highlight the actual expression that has the
1159      // wrong type.
1160      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1161        << "an NSString" << IdxExpr->getSourceRange();
1162      return;
1163    }
1164  } else if (!Ty->isPointerType() ||
1165             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
1166    // FIXME: Should highlight the actual expression that has the
1167    // wrong type.
1168    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1169      << "a string type" << IdxExpr->getSourceRange();
1170    return;
1171  }
1172
1173  // check the 3rd argument
1174  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1175  llvm::APSInt FirstArg(32);
1176  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1177    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1178      << "format" << 3 << FirstArgExpr->getSourceRange();
1179    return;
1180  }
1181
1182  // check if the function is variadic if the 3rd argument non-zero
1183  if (FirstArg != 0) {
1184    if (isFunctionOrMethodVariadic(d)) {
1185      ++NumArgs; // +1 for ...
1186    } else {
1187      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
1188      return;
1189    }
1190  }
1191
1192  // strftime requires FirstArg to be 0 because it doesn't read from any
1193  // variable the input is just the current time + the format string.
1194  if (is_strftime) {
1195    if (FirstArg != 0) {
1196      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1197        << FirstArgExpr->getSourceRange();
1198      return;
1199    }
1200  // if 0 it disables parameter checking (to use with e.g. va_list)
1201  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1202    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1203      << "format" << 3 << FirstArgExpr->getSourceRange();
1204    return;
1205  }
1206
1207  d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen),
1208                            Idx.getZExtValue(), FirstArg.getZExtValue()));
1209}
1210
1211static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
1212                                       Sema &S) {
1213  // check the attribute arguments.
1214  if (Attr.getNumArgs() != 0) {
1215    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1216    return;
1217  }
1218
1219  // Try to find the underlying union declaration.
1220  RecordDecl *RD = 0;
1221  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
1222  if (TD && TD->getUnderlyingType()->isUnionType())
1223    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
1224  else
1225    RD = dyn_cast<RecordDecl>(d);
1226
1227  if (!RD || !RD->isUnion()) {
1228    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1229      << Attr.getName() << 1 /*union*/;
1230    return;
1231  }
1232
1233  if (!RD->isDefinition()) {
1234    S.Diag(Attr.getLoc(),
1235        diag::warn_transparent_union_attribute_not_definition);
1236    return;
1237  }
1238
1239  RecordDecl::field_iterator Field = RD->field_begin(S.Context),
1240                          FieldEnd = RD->field_end(S.Context);
1241  if (Field == FieldEnd) {
1242    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
1243    return;
1244  }
1245
1246  FieldDecl *FirstField = *Field;
1247  QualType FirstType = FirstField->getType();
1248  if (FirstType->isFloatingType() || FirstType->isVectorType()) {
1249    S.Diag(FirstField->getLocation(),
1250           diag::warn_transparent_union_attribute_floating);
1251    return;
1252  }
1253
1254  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
1255  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
1256  for (; Field != FieldEnd; ++Field) {
1257    QualType FieldType = Field->getType();
1258    if (S.Context.getTypeSize(FieldType) != FirstSize ||
1259        S.Context.getTypeAlign(FieldType) != FirstAlign) {
1260      // Warn if we drop the attribute.
1261      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1262      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
1263                                 : S.Context.getTypeAlign(FieldType);
1264      S.Diag(Field->getLocation(),
1265          diag::warn_transparent_union_attribute_field_size_align)
1266        << isSize << Field->getDeclName() << FieldBits;
1267      unsigned FirstBits = isSize? FirstSize : FirstAlign;
1268      S.Diag(FirstField->getLocation(),
1269             diag::note_transparent_union_first_field_size_align)
1270        << isSize << FirstBits;
1271      return;
1272    }
1273  }
1274
1275  RD->addAttr(::new (S.Context) TransparentUnionAttr());
1276}
1277
1278static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1279  // check the attribute arguments.
1280  if (Attr.getNumArgs() != 1) {
1281    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1282    return;
1283  }
1284  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
1285  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
1286
1287  // Make sure that there is a string literal as the annotation's single
1288  // argument.
1289  if (!SE) {
1290    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
1291    return;
1292  }
1293  d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
1294                                                        SE->getByteLength())));
1295}
1296
1297static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1298  // check the attribute arguments.
1299  if (Attr.getNumArgs() > 1) {
1300    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1301    return;
1302  }
1303
1304  unsigned Align = 0;
1305  if (Attr.getNumArgs() == 0) {
1306    // FIXME: This should be the target specific maximum alignment.
1307    // (For now we just use 128 bits which is the maximum on X86).
1308    Align = 128;
1309    d->addAttr(::new (S.Context) AlignedAttr(Align));
1310    return;
1311  }
1312
1313  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
1314  llvm::APSInt Alignment(32);
1315  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1316    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1317      << "aligned" << alignmentExpr->getSourceRange();
1318    return;
1319  }
1320  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
1321    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
1322      << alignmentExpr->getSourceRange();
1323    return;
1324  }
1325
1326  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
1327}
1328
1329/// HandleModeAttr - This attribute modifies the width of a decl with
1330/// primitive type.
1331///
1332/// Despite what would be logical, the mode attribute is a decl attribute,
1333/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
1334/// 'G' be HImode, not an intermediate pointer.
1335///
1336static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1337  // This attribute isn't documented, but glibc uses it.  It changes
1338  // the width of an int or unsigned int to the specified size.
1339
1340  // Check that there aren't any arguments
1341  if (Attr.getNumArgs() != 0) {
1342    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1343    return;
1344  }
1345
1346  IdentifierInfo *Name = Attr.getParameterName();
1347  if (!Name) {
1348    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1349    return;
1350  }
1351  const char *Str = Name->getName();
1352  unsigned Len = Name->getLength();
1353
1354  // Normalize the attribute name, __foo__ becomes foo.
1355  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
1356      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
1357    Str += 2;
1358    Len -= 4;
1359  }
1360
1361  unsigned DestWidth = 0;
1362  bool IntegerMode = true;
1363  bool ComplexMode = false;
1364  switch (Len) {
1365  case 2:
1366    switch (Str[0]) {
1367    case 'Q': DestWidth = 8; break;
1368    case 'H': DestWidth = 16; break;
1369    case 'S': DestWidth = 32; break;
1370    case 'D': DestWidth = 64; break;
1371    case 'X': DestWidth = 96; break;
1372    case 'T': DestWidth = 128; break;
1373    }
1374    if (Str[1] == 'F') {
1375      IntegerMode = false;
1376    } else if (Str[1] == 'C') {
1377      IntegerMode = false;
1378      ComplexMode = true;
1379    } else if (Str[1] != 'I') {
1380      DestWidth = 0;
1381    }
1382    break;
1383  case 4:
1384    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1385    // pointer on PIC16 and other embedded platforms.
1386    if (!memcmp(Str, "word", 4))
1387      DestWidth = S.Context.Target.getPointerWidth(0);
1388    if (!memcmp(Str, "byte", 4))
1389      DestWidth = S.Context.Target.getCharWidth();
1390    break;
1391  case 7:
1392    if (!memcmp(Str, "pointer", 7))
1393      DestWidth = S.Context.Target.getPointerWidth(0);
1394    break;
1395  }
1396
1397  QualType OldTy;
1398  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1399    OldTy = TD->getUnderlyingType();
1400  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1401    OldTy = VD->getType();
1402  else {
1403    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1404      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1405    return;
1406  }
1407
1408  if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType())
1409    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
1410  else if (IntegerMode) {
1411    if (!OldTy->isIntegralType())
1412      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1413  } else if (ComplexMode) {
1414    if (!OldTy->isComplexType())
1415      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1416  } else {
1417    if (!OldTy->isFloatingType())
1418      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1419  }
1420
1421  // FIXME: Sync this with InitializePredefinedMacros; we need to match
1422  // int8_t and friends, at least with glibc.
1423  // FIXME: Make sure 32/64-bit integers don't get defined to types of
1424  // the wrong width on unusual platforms.
1425  // FIXME: Make sure floating-point mappings are accurate
1426  // FIXME: Support XF and TF types
1427  QualType NewTy;
1428  switch (DestWidth) {
1429  case 0:
1430    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1431    return;
1432  default:
1433    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1434    return;
1435  case 8:
1436    if (!IntegerMode) {
1437      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1438      return;
1439    }
1440    if (OldTy->isSignedIntegerType())
1441      NewTy = S.Context.SignedCharTy;
1442    else
1443      NewTy = S.Context.UnsignedCharTy;
1444    break;
1445  case 16:
1446    if (!IntegerMode) {
1447      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1448      return;
1449    }
1450    if (OldTy->isSignedIntegerType())
1451      NewTy = S.Context.ShortTy;
1452    else
1453      NewTy = S.Context.UnsignedShortTy;
1454    break;
1455  case 32:
1456    if (!IntegerMode)
1457      NewTy = S.Context.FloatTy;
1458    else if (OldTy->isSignedIntegerType())
1459      NewTy = S.Context.IntTy;
1460    else
1461      NewTy = S.Context.UnsignedIntTy;
1462    break;
1463  case 64:
1464    if (!IntegerMode)
1465      NewTy = S.Context.DoubleTy;
1466    else if (OldTy->isSignedIntegerType())
1467      NewTy = S.Context.LongLongTy;
1468    else
1469      NewTy = S.Context.UnsignedLongLongTy;
1470    break;
1471  case 96:
1472    NewTy = S.Context.LongDoubleTy;
1473    break;
1474  case 128:
1475    if (!IntegerMode) {
1476      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1477      return;
1478    }
1479    NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType());
1480    break;
1481  }
1482
1483  if (ComplexMode) {
1484    NewTy = S.Context.getComplexType(NewTy);
1485  }
1486
1487  // Install the new type.
1488  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1489    TD->setUnderlyingType(NewTy);
1490  else
1491    cast<ValueDecl>(D)->setType(NewTy);
1492}
1493
1494static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1495  // check the attribute arguments.
1496  if (Attr.getNumArgs() > 0) {
1497    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1498    return;
1499  }
1500
1501  if (!isFunctionOrMethod(d)) {
1502    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1503      << Attr.getName() << 0 /*function*/;
1504    return;
1505  }
1506
1507  d->addAttr(::new (S.Context) NodebugAttr());
1508}
1509
1510static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1511  // check the attribute arguments.
1512  if (Attr.getNumArgs() != 0) {
1513    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1514    return;
1515  }
1516
1517  if (!isa<FunctionDecl>(d)) {
1518    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1519    << Attr.getName() << 0 /*function*/;
1520    return;
1521  }
1522
1523  d->addAttr(::new (S.Context) NoinlineAttr());
1524}
1525
1526static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1527  // check the attribute arguments.
1528  if (Attr.getNumArgs() != 0) {
1529    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1530    return;
1531  }
1532
1533  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
1534  if (Fn == 0) {
1535    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1536      << Attr.getName() << 0 /*function*/;
1537    return;
1538  }
1539
1540  if (!Fn->isInline()) {
1541    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
1542    return;
1543  }
1544
1545  d->addAttr(::new (S.Context) GNUInlineAttr());
1546}
1547
1548static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1549  // check the attribute arguments.
1550  if (Attr.getNumArgs() != 1) {
1551    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1552    return;
1553  }
1554
1555  if (!isFunctionOrMethod(d)) {
1556    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1557    << Attr.getName() << 0 /*function*/;
1558    return;
1559  }
1560
1561  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
1562  llvm::APSInt NumParams(32);
1563  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
1564    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1565      << "regparm" << NumParamsExpr->getSourceRange();
1566    return;
1567  }
1568
1569  if (S.Context.Target.getRegParmMax() == 0) {
1570    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
1571      << NumParamsExpr->getSourceRange();
1572    return;
1573  }
1574
1575  if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
1576    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
1577      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
1578    return;
1579  }
1580
1581  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
1582}
1583
1584//===----------------------------------------------------------------------===//
1585// Checker-specific attribute handlers.
1586//===----------------------------------------------------------------------===//
1587
1588static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
1589                                        Sema &S) {
1590
1591  QualType RetTy;
1592
1593  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
1594    RetTy = MD->getResultType();
1595  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
1596    RetTy = FD->getResultType();
1597  else {
1598    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1599        << Attr.getName() << 3 /* function or method */;
1600    return;
1601  }
1602
1603  if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAsPointerType())) {
1604    S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
1605      << Attr.getName();
1606    return;
1607  }
1608
1609  switch (Attr.getKind()) {
1610    default:
1611      assert(0 && "invalid ownership attribute");
1612      return;
1613    case AttributeList::AT_cf_returns_retained:
1614      d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
1615      return;
1616    case AttributeList::AT_ns_returns_retained:
1617      d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
1618      return;
1619  };
1620}
1621
1622//===----------------------------------------------------------------------===//
1623// Top Level Sema Entry Points
1624//===----------------------------------------------------------------------===//
1625
1626/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1627/// the attribute applies to decls.  If the attribute is a type attribute, just
1628/// silently ignore it.
1629static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
1630  switch (Attr.getKind()) {
1631  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1632  case AttributeList::AT_address_space:
1633  case AttributeList::AT_objc_gc:
1634    // Ignore these, these are type attributes, handled by ProcessTypeAttributes.
1635    break;
1636  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
1637  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1638  case AttributeList::AT_always_inline:
1639    HandleAlwaysInlineAttr  (D, Attr, S); break;
1640  case AttributeList::AT_analyzer_noreturn:
1641    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
1642  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
1643  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1644  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
1645  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1646  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
1647  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
1648  case AttributeList::AT_ext_vector_type:
1649    HandleExtVectorTypeAttr(D, Attr, S);
1650    break;
1651  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1652  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
1653  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr(D, Attr, S); break;
1654  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
1655  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
1656  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
1657  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
1658
1659  // Checker-specific.
1660  case AttributeList::AT_ns_returns_retained:
1661  case AttributeList::AT_cf_returns_retained:
1662    HandleNSReturnsRetainedAttr(D, Attr, S); break;
1663
1664  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
1665  case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
1666  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
1667  case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
1668  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
1669  case AttributeList::AT_used:        HandleUsedAttr      (D, Attr, S); break;
1670  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
1671  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
1672  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
1673    break;
1674  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
1675  case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break;
1676  case AttributeList::AT_transparent_union:
1677    HandleTransparentUnionAttr(D, Attr, S);
1678    break;
1679  case AttributeList::AT_objc_exception:
1680    HandleObjCExceptionAttr(D, Attr, S);
1681    break;
1682  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
1683  case AttributeList::AT_nsobject:    HandleObjCNSObject  (D, Attr, S); break;
1684  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1685  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1686  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1687  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1688  case AttributeList::AT_cleanup:     HandleCleanupAttr   (D, Attr, S); break;
1689  case AttributeList::AT_nodebug:     HandleNodebugAttr   (D, Attr, S); break;
1690  case AttributeList::AT_noinline:    HandleNoinlineAttr  (D, Attr, S); break;
1691  case AttributeList::AT_regparm:     HandleRegparmAttr   (D, Attr, S); break;
1692  case AttributeList::IgnoredAttribute:
1693  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
1694    // Just ignore
1695    break;
1696  default:
1697    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1698    break;
1699  }
1700}
1701
1702/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1703/// attribute list to the specified decl, ignoring any type attributes.
1704void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
1705  while (AttrList) {
1706    ProcessDeclAttribute(D, *AttrList, *this);
1707    AttrList = AttrList->getNext();
1708  }
1709}
1710
1711/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
1712/// it, apply them to D.  This is a bit tricky because PD can have attributes
1713/// specified in many different places, and we need to find and apply them all.
1714void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
1715  // Apply decl attributes from the DeclSpec if present.
1716  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
1717    ProcessDeclAttributeList(D, Attrs);
1718
1719  // Walk the declarator structure, applying decl attributes that were in a type
1720  // position to the decl itself.  This handles cases like:
1721  //   int *__attr__(x)** D;
1722  // when X is a decl attribute.
1723  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
1724    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
1725      ProcessDeclAttributeList(D, Attrs);
1726
1727  // Finally, apply any attributes on the decl itself.
1728  if (const AttributeList *Attrs = PD.getAttributes())
1729    ProcessDeclAttributeList(D, Attrs);
1730}
1731