SemaDeclAttr.cpp revision 0a2da71034fea55ee786387314eae704b91e2f9b
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/Diagnostic.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Parse/DeclSpec.h"
21#include <llvm/ADT/StringExtras.h>
22using namespace clang;
23
24//===----------------------------------------------------------------------===//
25//  Helper functions
26//===----------------------------------------------------------------------===//
27
28static const FunctionType *getFunctionType(Decl *d) {
29  QualType Ty;
30  if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
31    Ty = decl->getType();
32  else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
33    Ty = decl->getType();
34  else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
35    Ty = decl->getUnderlyingType();
36  else
37    return 0;
38
39  if (Ty->isFunctionPointerType())
40    Ty = Ty->getAsPointerType()->getPointeeType();
41
42  return Ty->getAsFunctionType();
43}
44
45// FIXME: We should provide an abstraction around a method or function
46// to provide the following bits of information.
47
48/// isFunctionOrMethod - Return true if the given decl has function
49/// type (function or function-typed variable) or an Objective-C
50/// method.
51static bool isFunctionOrMethod(Decl *d) {
52  return getFunctionType(d) || isa<ObjCMethodDecl>(d);
53}
54
55/// hasFunctionProto - Return true if the given decl has a argument
56/// information. This decl should have already passed
57/// isFunctionOrMethod.
58static bool hasFunctionProto(Decl *d) {
59  if (const FunctionType *FnTy = getFunctionType(d)) {
60    return isa<FunctionTypeProto>(FnTy);
61  } else {
62    assert(isa<ObjCMethodDecl>(d));
63    return true;
64  }
65}
66
67/// getFunctionOrMethodNumArgs - Return number of function or method
68/// arguments. It is an error to call this on a K&R function (use
69/// hasFunctionProto first).
70static unsigned getFunctionOrMethodNumArgs(Decl *d) {
71  if (const FunctionType *FnTy = getFunctionType(d)) {
72    const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy);
73    return proto->getNumArgs();
74  } else {
75    return cast<ObjCMethodDecl>(d)->getNumParams();
76  }
77}
78
79static QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) {
80  if (const FunctionType *FnTy = getFunctionType(d)) {
81    const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy);
82    return proto->getArgType(Idx);
83  } else {
84    return cast<ObjCMethodDecl>(d)->getParamDecl(Idx)->getType();
85  }
86}
87
88static bool isFunctionOrMethodVariadic(Decl *d) {
89  if (const FunctionType *FnTy = getFunctionType(d)) {
90    const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy);
91    return proto->isVariadic();
92  } else {
93    return cast<ObjCMethodDecl>(d)->isVariadic();
94  }
95}
96
97static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
98  const PointerType *PT = T->getAsPointerType();
99  if (!PT)
100    return false;
101
102  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType();
103  if (!ClsT)
104    return false;
105
106  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
107
108  // FIXME: Should we walk the chain of classes?
109  return ClsName == &Ctx.Idents.get("NSString") ||
110         ClsName == &Ctx.Idents.get("NSMutableString");
111}
112
113static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
114  const PointerType *PT = T->getAsPointerType();
115  if (!PT)
116    return false;
117
118  const RecordType *RT = PT->getPointeeType()->getAsRecordType();
119  if (!RT)
120    return false;
121
122  const RecordDecl *RD = RT->getDecl();
123  if (RD->getTagKind() != TagDecl::TK_struct)
124    return false;
125
126  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
127}
128
129//===----------------------------------------------------------------------===//
130// Attribute Implementations
131//===----------------------------------------------------------------------===//
132
133// FIXME: All this manual attribute parsing code is gross. At the
134// least add some helper functions to check most argument patterns (#
135// and types of args).
136
137static void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
138                                    Sema &S) {
139  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
140  if (tDecl == 0) {
141    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
142    return;
143  }
144
145  QualType curType = tDecl->getUnderlyingType();
146  // check the attribute arguments.
147  if (Attr.getNumArgs() != 1) {
148    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
149           std::string("1"));
150    return;
151  }
152  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
153  llvm::APSInt vecSize(32);
154  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
155    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
156           "ext_vector_type", sizeExpr->getSourceRange());
157    return;
158  }
159  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
160  // in conjunction with complex types (pointers, arrays, functions, etc.).
161  if (!curType->isIntegerType() && !curType->isRealFloatingType()) {
162    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
163           curType.getAsString());
164    return;
165  }
166  // unlike gcc's vector_size attribute, the size is specified as the
167  // number of elements, not the number of bytes.
168  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
169
170  if (vectorSize == 0) {
171    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
172           sizeExpr->getSourceRange());
173    return;
174  }
175  // Instantiate/Install the vector type, the number of elements is > 0.
176  tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize));
177  // Remember this typedef decl, we will need it later for diagnostics.
178  S.ExtVectorDecls.push_back(tDecl);
179}
180
181
182/// HandleVectorSizeAttribute - this attribute is only applicable to
183/// integral and float scalars, although arrays, pointers, and function
184/// return values are allowed in conjunction with this construct. Aggregates
185/// with this attribute are invalid, even if they are of the same size as a
186/// corresponding scalar.
187/// The raw attribute should contain precisely 1 argument, the vector size
188/// for the variable, measured in bytes. If curType and rawAttr are well
189/// formed, this routine will return a new vector type.
190static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
191  QualType CurType;
192  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
193    CurType = VD->getType();
194  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
195    CurType = TD->getUnderlyingType();
196  else {
197    S.Diag(D->getLocation(), diag::err_attr_wrong_decl,
198           std::string("vector_size"),
199           SourceRange(Attr.getLoc(), Attr.getLoc()));
200    return;
201  }
202
203  // Check the attribute arugments.
204  if (Attr.getNumArgs() != 1) {
205    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
206           std::string("1"));
207    return;
208  }
209  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
210  llvm::APSInt vecSize(32);
211  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
212    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
213           "vector_size", sizeExpr->getSourceRange());
214    return;
215  }
216  // navigate to the base type - we need to provide for vector pointers,
217  // vector arrays, and functions returning vectors.
218  if (CurType->isPointerType() || CurType->isArrayType() ||
219      CurType->isFunctionType()) {
220    assert(0 && "HandleVector(): Complex type construction unimplemented");
221    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
222     do {
223     if (PointerType *PT = dyn_cast<PointerType>(canonType))
224     canonType = PT->getPointeeType().getTypePtr();
225     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
226     canonType = AT->getElementType().getTypePtr();
227     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
228     canonType = FT->getResultType().getTypePtr();
229     } while (canonType->isPointerType() || canonType->isArrayType() ||
230     canonType->isFunctionType());
231     */
232  }
233  // the base type must be integer or float.
234  if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
235    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
236           CurType.getAsString());
237    return;
238  }
239  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
240  // vecSize is specified in bytes - convert to bits.
241  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
242
243  // the vector size needs to be an integral multiple of the type size.
244  if (vectorSize % typeSize) {
245    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size,
246           sizeExpr->getSourceRange());
247    return;
248  }
249  if (vectorSize == 0) {
250    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
251           sizeExpr->getSourceRange());
252    return;
253  }
254
255  // Success! Instantiate the vector type, the number of elements is > 0, and
256  // not required to be a power of 2, unlike GCC.
257  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
258
259  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
260    VD->setType(CurType);
261  else
262    cast<TypedefDecl>(D)->setUnderlyingType(CurType);
263}
264
265static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
266  // check the attribute arguments.
267  if (Attr.getNumArgs() > 0) {
268    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
269           std::string("0"));
270    return;
271  }
272
273  if (TagDecl *TD = dyn_cast<TagDecl>(d))
274    TD->addAttr(new PackedAttr(1));
275  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
276    // If the alignment is less than or equal to 8 bits, the packed attribute
277    // has no effect.
278    if (!FD->getType()->isIncompleteType() &&
279        S.Context.getTypeAlign(FD->getType()) <= 8)
280      S.Diag(Attr.getLoc(),
281             diag::warn_attribute_ignored_for_field_of_type,
282             Attr.getName()->getName(), FD->getType().getAsString());
283    else
284      FD->addAttr(new PackedAttr(1));
285  } else
286    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored,
287           Attr.getName()->getName());
288}
289
290static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
291  // check the attribute arguments.
292  if (Attr.getNumArgs() > 0) {
293    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
294           std::string("0"));
295    return;
296  }
297
298  // The IBOutlet attribute only applies to instance variables of Objective-C
299  // classes.
300  if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d))
301    ID->addAttr(new IBOutletAttr());
302  else
303    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar);
304}
305
306static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
307  // GCC ignores the nonnull attribute on K&R style function
308  // prototypes, so we ignore it as well
309  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
310    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
311           "nonnull", "function");
312    return;
313  }
314
315  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
316
317  // The nonnull attribute only applies to pointers.
318  llvm::SmallVector<unsigned, 10> NonNullArgs;
319
320  for (AttributeList::arg_iterator I=Attr.arg_begin(),
321                                   E=Attr.arg_end(); I!=E; ++I) {
322
323
324    // The argument must be an integer constant expression.
325    Expr *Ex = static_cast<Expr *>(Attr.getArg(0));
326    llvm::APSInt ArgNum(32);
327    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
328      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
329             "nonnull", Ex->getSourceRange());
330      return;
331    }
332
333    unsigned x = (unsigned) ArgNum.getZExtValue();
334
335    if (x < 1 || x > NumArgs) {
336      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
337             "nonnull", llvm::utostr_32(I.getArgNum()), Ex->getSourceRange());
338      return;
339    }
340
341    --x;
342
343    // Is the function argument a pointer type?
344    if (!getFunctionOrMethodArgType(d, x)->isPointerType()) {
345      // FIXME: Should also highlight argument in decl.
346      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only,
347             "nonnull", Ex->getSourceRange());
348      continue;
349    }
350
351    NonNullArgs.push_back(x);
352  }
353
354  // If no arguments were specified to __attribute__((nonnull)) then all
355  // pointer arguments have a nonnull attribute.
356  if (NonNullArgs.empty()) {
357    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I)
358      if (getFunctionOrMethodArgType(d, I)->isPointerType())
359        NonNullArgs.push_back(I);
360
361    if (NonNullArgs.empty()) {
362      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
363      return;
364    }
365  }
366
367  unsigned* start = &NonNullArgs[0];
368  unsigned size = NonNullArgs.size();
369  std::sort(start, start + size);
370  d->addAttr(new NonNullAttr(start, size));
371}
372
373static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
374  // check the attribute arguments.
375  if (Attr.getNumArgs() != 1) {
376    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
377           std::string("1"));
378    return;
379  }
380
381  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
382  Arg = Arg->IgnoreParenCasts();
383  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
384
385  if (Str == 0 || Str->isWide()) {
386    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
387           "alias", std::string("1"));
388    return;
389  }
390
391  const char *Alias = Str->getStrData();
392  unsigned AliasLen = Str->getByteLength();
393
394  // FIXME: check if target symbol exists in current file
395
396  d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
397}
398
399static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
400                                   Sema &S) {
401  // check the attribute arguments.
402  if (Attr.getNumArgs() != 0) {
403    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
404           std::string("0"));
405    return;
406  }
407
408  d->addAttr(new AlwaysInlineAttr());
409}
410
411static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
412  // check the attribute arguments.
413  if (Attr.getNumArgs() != 0) {
414    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
415           std::string("0"));
416    return;
417  }
418
419  if (!isFunctionOrMethod(d)) {
420    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
421           "noreturn", "function");
422    return;
423  }
424
425  d->addAttr(new NoReturnAttr());
426}
427
428static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
429  // check the attribute arguments.
430  if (Attr.getNumArgs() != 0) {
431    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
432           std::string("0"));
433    return;
434  }
435
436  if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) {
437    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
438           "unused", "variable and function");
439    return;
440  }
441
442  d->addAttr(new UnusedAttr());
443}
444
445static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
446  // check the attribute arguments.
447  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
448    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
449    return;
450  }
451
452  int priority = 65535; // FIXME: Do not hardcode such constants.
453  if (Attr.getNumArgs() > 0) {
454    Expr *E = static_cast<Expr *>(Attr.getArg(0));
455    llvm::APSInt Idx(32);
456    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
457      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
458             "constructor", "1", E->getSourceRange());
459      return;
460    }
461    priority = Idx.getZExtValue();
462  }
463
464  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
465  if (!Fn) {
466    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
467           "constructor", "function");
468    return;
469  }
470
471  d->addAttr(new ConstructorAttr(priority));
472}
473
474static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
475  // check the attribute arguments.
476  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
477    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
478    return;
479  }
480
481  int priority = 65535; // FIXME: Do not hardcode such constants.
482  if (Attr.getNumArgs() > 0) {
483    Expr *E = static_cast<Expr *>(Attr.getArg(0));
484    llvm::APSInt Idx(32);
485    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
486      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
487             "destructor", "1", E->getSourceRange());
488      return;
489    }
490    priority = Idx.getZExtValue();
491  }
492
493  if (!isa<FunctionDecl>(d)) {
494    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
495           "destructor", "function");
496    return;
497  }
498
499  d->addAttr(new DestructorAttr(priority));
500}
501
502static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
503  // check the attribute arguments.
504  if (Attr.getNumArgs() != 0) {
505    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
506           std::string("0"));
507    return;
508  }
509
510  d->addAttr(new DeprecatedAttr());
511}
512
513static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
514  // check the attribute arguments.
515  if (Attr.getNumArgs() != 1) {
516    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
517           std::string("1"));
518    return;
519  }
520
521  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
522  Arg = Arg->IgnoreParenCasts();
523  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
524
525  if (Str == 0 || Str->isWide()) {
526    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
527           "visibility", std::string("1"));
528    return;
529  }
530
531  const char *TypeStr = Str->getStrData();
532  unsigned TypeLen = Str->getByteLength();
533  VisibilityAttr::VisibilityTypes type;
534
535  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
536    type = VisibilityAttr::DefaultVisibility;
537  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
538    type = VisibilityAttr::HiddenVisibility;
539  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
540    type = VisibilityAttr::HiddenVisibility; // FIXME
541  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
542    type = VisibilityAttr::ProtectedVisibility;
543  else {
544    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
545           "visibility", TypeStr);
546    return;
547  }
548
549  d->addAttr(new VisibilityAttr(type));
550}
551
552static void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) {
553  if (!Attr.getParameterName()) {
554    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
555           "objc_gc", std::string("1"));
556    return;
557  }
558
559  if (Attr.getNumArgs() != 0) {
560    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
561           std::string("1"));
562    return;
563  }
564
565  const char *TypeStr = Attr.getParameterName()->getName();
566  unsigned TypeLen = Attr.getParameterName()->getLength();
567
568  ObjCGCAttr::GCAttrTypes type;
569
570  if (TypeLen == 4 && !memcmp(TypeStr, "weak", 4))
571    type = ObjCGCAttr::Weak;
572  else if (TypeLen == 6 && !memcmp(TypeStr, "strong", 6))
573    type = ObjCGCAttr::Strong;
574  else {
575    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
576           "objc_gc", TypeStr);
577    return;
578  }
579
580  d->addAttr(new ObjCGCAttr(type));
581}
582
583static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
584  if (!Attr.getParameterName()) {
585    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
586           "blocks", std::string("1"));
587    return;
588  }
589
590  if (Attr.getNumArgs() != 0) {
591    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
592           std::string("1"));
593    return;
594  }
595  const char *TypeStr = Attr.getParameterName()->getName();
596  unsigned TypeLen = Attr.getParameterName()->getLength();
597
598  BlocksAttr::BlocksAttrTypes type;
599
600  if (TypeLen == 5 && !memcmp(TypeStr, "byref", 5))
601    type = BlocksAttr::ByRef;
602  else {
603    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
604           "blocks", TypeStr);
605    return;
606  }
607
608  d->addAttr(new BlocksAttr(type));
609}
610
611static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
612  // check the attribute arguments.
613  if (Attr.getNumArgs() > 2) {
614    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0, 1 or 2");
615    return;
616  }
617
618  int sentinel = 0;
619  if (Attr.getNumArgs() > 0) {
620    Expr *E = static_cast<Expr *>(Attr.getArg(0));
621    llvm::APSInt Idx(32);
622    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
623      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
624             "sentinel", "1", E->getSourceRange());
625      return;
626    }
627    sentinel = Idx.getZExtValue();
628
629    if (sentinel < 0) {
630      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero,
631             E->getSourceRange());
632      return;
633    }
634  }
635
636  int nullPos = 0;
637  if (Attr.getNumArgs() > 1) {
638    Expr *E = static_cast<Expr *>(Attr.getArg(1));
639    llvm::APSInt Idx(32);
640    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
641      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
642             "sentinel", "2", E->getSourceRange());
643      return;
644    }
645    nullPos = Idx.getZExtValue();
646
647    if (nullPos > 1 || nullPos < 0) {
648      // FIXME: This error message could be improved, it would be nice
649      // to say what the bounds actually are.
650      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one,
651             E->getSourceRange());
652      return;
653    }
654  }
655
656  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
657    QualType FT = FD->getType();
658    if (!FT->getAsFunctionTypeProto()->isVariadic()) {
659      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
660      return;
661    }
662  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
663    if (!MD->isVariadic()) {
664      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
665      return;
666    }
667  } else {
668    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
669           "sentinel", "function or method");
670    return;
671  }
672
673  // FIXME: Actually create the attribute.
674}
675
676static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
677  // check the attribute arguments.
678  if (Attr.getNumArgs() != 0) {
679    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
680           std::string("0"));
681    return;
682  }
683
684  d->addAttr(new WeakAttr());
685}
686
687static void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
688  // check the attribute arguments.
689  if (Attr.getNumArgs() != 0) {
690    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
691           std::string("0"));
692    return;
693  }
694
695  d->addAttr(new DLLImportAttr());
696}
697
698static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
699  // check the attribute arguments.
700  if (Attr.getNumArgs() != 0) {
701    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
702           std::string("0"));
703    return;
704  }
705
706  d->addAttr(new DLLExportAttr());
707}
708
709static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
710  // check the attribute arguments.
711  if (Attr.getNumArgs() != 0) {
712    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
713           std::string("0"));
714    return;
715  }
716
717  d->addAttr(new StdCallAttr());
718}
719
720static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
721  // check the attribute arguments.
722  if (Attr.getNumArgs() != 0) {
723    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
724           std::string("0"));
725    return;
726  }
727
728  d->addAttr(new FastCallAttr());
729}
730
731static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
732  // check the attribute arguments.
733  if (Attr.getNumArgs() != 0) {
734    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
735           std::string("0"));
736    return;
737  }
738
739  d->addAttr(new NoThrowAttr());
740}
741
742static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
743  // check the attribute arguments.
744  if (Attr.getNumArgs() != 0) {
745    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
746           std::string("0"));
747    return;
748  }
749
750  d->addAttr(new ConstAttr());
751}
752
753static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
754  // check the attribute arguments.
755  if (Attr.getNumArgs() != 0) {
756    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
757           std::string("0"));
758    return;
759  }
760
761  d->addAttr(new PureAttr());
762}
763
764/// Handle __attribute__((format(type,idx,firstarg))) attributes
765/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
766static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
767
768  if (!Attr.getParameterName()) {
769    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
770           "format", std::string("1"));
771    return;
772  }
773
774  if (Attr.getNumArgs() != 2) {
775    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
776           std::string("3"));
777    return;
778  }
779
780  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
781    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
782           "format", "function");
783    return;
784  }
785
786  // FIXME: in C++ the implicit 'this' function parameter also counts.
787  // this is needed in order to be compatible with GCC
788  // the index must start in 1 and the limit is numargs+1
789  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
790  unsigned FirstIdx = 1;
791
792  const char *Format = Attr.getParameterName()->getName();
793  unsigned FormatLen = Attr.getParameterName()->getLength();
794
795  // Normalize the argument, __foo__ becomes foo.
796  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
797      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
798    Format += 2;
799    FormatLen -= 4;
800  }
801
802  bool Supported = false;
803  bool is_NSString = false;
804  bool is_strftime = false;
805  bool is_CFString = false;
806
807  switch (FormatLen) {
808  default: break;
809  case 5: Supported = !memcmp(Format, "scanf", 5); break;
810  case 6: Supported = !memcmp(Format, "printf", 6); break;
811  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
812  case 8:
813    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
814                (is_NSString = !memcmp(Format, "NSString", 8)) ||
815                (is_CFString = !memcmp(Format, "CFString", 8));
816    break;
817  }
818
819  if (!Supported) {
820    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
821           "format", Attr.getParameterName()->getName());
822    return;
823  }
824
825  // checks for the 2nd argument
826  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
827  llvm::APSInt Idx(32);
828  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
829    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
830           "format", std::string("2"), IdxExpr->getSourceRange());
831    return;
832  }
833
834  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
835    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
836           "format", std::string("2"), IdxExpr->getSourceRange());
837    return;
838  }
839
840  // FIXME: Do we need to bounds check?
841  unsigned ArgIdx = Idx.getZExtValue() - 1;
842
843  // make sure the format string is really a string
844  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
845
846  if (is_CFString) {
847    if (!isCFStringType(Ty, S.Context)) {
848      S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
849             "a CFString", IdxExpr->getSourceRange());
850      return;
851    }
852  } else if (is_NSString) {
853    // FIXME: do we need to check if the type is NSString*?  What are
854    //  the semantics?
855    if (!isNSStringType(Ty, S.Context)) {
856      // FIXME: Should highlight the actual expression that has the
857      // wrong type.
858      S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
859             "an NSString", IdxExpr->getSourceRange());
860      return;
861    }
862  } else if (!Ty->isPointerType() ||
863             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
864    // FIXME: Should highlight the actual expression that has the
865    // wrong type.
866    S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
867           "a string type", IdxExpr->getSourceRange());
868    return;
869  }
870
871  // check the 3rd argument
872  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
873  llvm::APSInt FirstArg(32);
874  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
875    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
876           "format", std::string("3"), FirstArgExpr->getSourceRange());
877    return;
878  }
879
880  // check if the function is variadic if the 3rd argument non-zero
881  if (FirstArg != 0) {
882    if (isFunctionOrMethodVariadic(d)) {
883      ++NumArgs; // +1 for ...
884    } else {
885      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
886      return;
887    }
888  }
889
890  // strftime requires FirstArg to be 0 because it doesn't read from any variable
891  // the input is just the current time + the format string
892  if (is_strftime) {
893    if (FirstArg != 0) {
894      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter,
895             FirstArgExpr->getSourceRange());
896      return;
897    }
898  // if 0 it disables parameter checking (to use with e.g. va_list)
899  } else if (FirstArg != 0 && FirstArg != NumArgs) {
900    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
901           "format", std::string("3"), FirstArgExpr->getSourceRange());
902    return;
903  }
904
905  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
906                            Idx.getZExtValue(), FirstArg.getZExtValue()));
907}
908
909static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
910                                       Sema &S) {
911  // check the attribute arguments.
912  if (Attr.getNumArgs() != 0) {
913    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
914         std::string("0"));
915    return;
916  }
917
918  // FIXME: This shouldn't be restricted to typedefs
919  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
920  if (!TD || !TD->getUnderlyingType()->isUnionType()) {
921    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
922         "transparent_union", "union");
923    return;
924  }
925
926  RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
927
928  // FIXME: Should we do a check for RD->isDefinition()?
929
930  // FIXME: This isn't supposed to be restricted to pointers, but otherwise
931  // we might silently generate incorrect code; see following code
932  for (int i = 0; i < RD->getNumMembers(); i++) {
933    if (!RD->getMember(i)->getType()->isPointerType()) {
934      S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer);
935      return;
936    }
937  }
938
939  // FIXME: This is a complete hack; we should be properly propagating
940  // transparent_union through Sema.  That said, this is close enough to
941  // correctly compile all the common cases of transparent_union without
942  // errors or warnings
943  QualType NewTy = S.Context.VoidPtrTy;
944  NewTy.addConst();
945  TD->setUnderlyingType(NewTy);
946}
947
948static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
949  // check the attribute arguments.
950  if (Attr.getNumArgs() != 1) {
951    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
952           std::string("1"));
953    return;
954  }
955  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
956  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
957
958  // Make sure that there is a string literal as the annotation's single
959  // argument.
960  if (!SE) {
961    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
962    return;
963  }
964  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
965                                          SE->getByteLength())));
966}
967
968static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
969  // check the attribute arguments.
970  if (Attr.getNumArgs() > 1) {
971    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
972           std::string("1"));
973    return;
974  }
975
976  unsigned Align = 0;
977  if (Attr.getNumArgs() == 0) {
978    // FIXME: This should be the target specific maximum alignment.
979    // (For now we just use 128 bits which is the maximum on X86.
980    Align = 128;
981    return;
982  }
983
984  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
985  llvm::APSInt Alignment(32);
986  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
987    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
988           "aligned", alignmentExpr->getSourceRange());
989    return;
990  }
991  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
992}
993
994/// HandleModeAttr - This attribute modifies the width of a decl with
995/// primitive type.
996///
997/// Despite what would be logical, the mode attribute is a decl attribute,
998/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
999/// 'G' be HImode, not an intermediate pointer.
1000///
1001static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1002  // This attribute isn't documented, but glibc uses it.  It changes
1003  // the width of an int or unsigned int to the specified size.
1004
1005  // Check that there aren't any arguments
1006  if (Attr.getNumArgs() != 0) {
1007    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
1008           std::string("0"));
1009    return;
1010  }
1011
1012  IdentifierInfo *Name = Attr.getParameterName();
1013  if (!Name) {
1014    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1015    return;
1016  }
1017  const char *Str = Name->getName();
1018  unsigned Len = Name->getLength();
1019
1020  // Normalize the attribute name, __foo__ becomes foo.
1021  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
1022      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
1023    Str += 2;
1024    Len -= 4;
1025  }
1026
1027  unsigned DestWidth = 0;
1028  bool IntegerMode = true;
1029  switch (Len) {
1030  case 2:
1031    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
1032    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
1033    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
1034    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
1035    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
1036    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
1037    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
1038    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
1039    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
1040    break;
1041  case 4:
1042    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1043    // pointer on PIC16 and other embedded platforms.
1044    if (!memcmp(Str, "word", 4))
1045      DestWidth = S.Context.Target.getPointerWidth(0);
1046    if (!memcmp(Str, "byte", 4))
1047      DestWidth = S.Context.Target.getCharWidth();
1048    break;
1049  case 7:
1050    if (!memcmp(Str, "pointer", 7))
1051      DestWidth = S.Context.Target.getPointerWidth(0);
1052    break;
1053  }
1054
1055  QualType OldTy;
1056  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1057    OldTy = TD->getUnderlyingType();
1058  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1059    OldTy = VD->getType();
1060  else {
1061    S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode",
1062           SourceRange(Attr.getLoc(), Attr.getLoc()));
1063    return;
1064  }
1065
1066  // FIXME: Need proper fixed-width types
1067  QualType NewTy;
1068  switch (DestWidth) {
1069  case 0:
1070    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName());
1071    return;
1072  default:
1073    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName());
1074    return;
1075  case 8:
1076    assert(IntegerMode);
1077    if (OldTy->isSignedIntegerType())
1078      NewTy = S.Context.SignedCharTy;
1079    else
1080      NewTy = S.Context.UnsignedCharTy;
1081    break;
1082  case 16:
1083    assert(IntegerMode);
1084    if (OldTy->isSignedIntegerType())
1085      NewTy = S.Context.ShortTy;
1086    else
1087      NewTy = S.Context.UnsignedShortTy;
1088    break;
1089  case 32:
1090    if (!IntegerMode)
1091      NewTy = S.Context.FloatTy;
1092    else if (OldTy->isSignedIntegerType())
1093      NewTy = S.Context.IntTy;
1094    else
1095      NewTy = S.Context.UnsignedIntTy;
1096    break;
1097  case 64:
1098    if (!IntegerMode)
1099      NewTy = S.Context.DoubleTy;
1100    else if (OldTy->isSignedIntegerType())
1101      NewTy = S.Context.LongLongTy;
1102    else
1103      NewTy = S.Context.UnsignedLongLongTy;
1104    break;
1105  }
1106
1107  if (!OldTy->getAsBuiltinType())
1108    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
1109  else if (!(IntegerMode && OldTy->isIntegerType()) &&
1110           !(!IntegerMode && OldTy->isFloatingType())) {
1111    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1112  }
1113
1114  // Install the new type.
1115  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1116    TD->setUnderlyingType(NewTy);
1117  else
1118    cast<ValueDecl>(D)->setType(NewTy);
1119}
1120
1121//===----------------------------------------------------------------------===//
1122// Top Level Sema Entry Points
1123//===----------------------------------------------------------------------===//
1124
1125/// HandleDeclAttribute - Apply the specific attribute to the specified decl if
1126/// the attribute applies to decls.  If the attribute is a type attribute, just
1127/// silently ignore it.
1128static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
1129  switch (Attr.getKind()) {
1130  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1131  case AttributeList::AT_address_space:
1132    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
1133    break;
1134  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
1135  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1136  case AttributeList::AT_always_inline:
1137    HandleAlwaysInlineAttr  (D, Attr, S); break;
1138  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
1139  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1140  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
1141  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1142  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
1143  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
1144  case AttributeList::AT_ext_vector_type:
1145    HandleExtVectorTypeAttr(D, Attr, S);
1146    break;
1147  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1148  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
1149  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
1150  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
1151  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
1152  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
1153  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
1154  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
1155  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
1156  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
1157  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
1158  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
1159  case AttributeList::AT_transparent_union:
1160    HandleTransparentUnionAttr(D, Attr, S);
1161    break;
1162  case AttributeList::AT_objc_gc:     HandleObjCGCAttr    (D, Attr, S); break;
1163  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1164  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1165  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1166  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1167  default:
1168#if 0
1169    // TODO: when we have the full set of attributes, warn about unknown ones.
1170    S.Diag(Attr->getLoc(), diag::warn_attribute_ignored,
1171           Attr->getName()->getName());
1172#endif
1173    break;
1174  }
1175}
1176
1177/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1178/// attribute list to the specified decl, ignoring any type attributes.
1179void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
1180  while (AttrList) {
1181    ProcessDeclAttribute(D, *AttrList, *this);
1182    AttrList = AttrList->getNext();
1183  }
1184}
1185
1186
1187/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
1188/// it, apply them to D.  This is a bit tricky because PD can have attributes
1189/// specified in many different places, and we need to find and apply them all.
1190void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
1191  // Apply decl attributes from the DeclSpec if present.
1192  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
1193    ProcessDeclAttributeList(D, Attrs);
1194
1195  // Walk the declarator structure, applying decl attributes that were in a type
1196  // position to the decl itself.  This handles cases like:
1197  //   int *__attr__(x)** D;
1198  // when X is a decl attribute.
1199  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
1200    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
1201      ProcessDeclAttributeList(D, Attrs);
1202
1203  // Finally, apply any attributes on the decl itself.
1204  if (const AttributeList *Attrs = PD.getAttributes())
1205    ProcessDeclAttributeList(D, Attrs);
1206}
1207
1208