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