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