SemaDeclAttr.cpp revision b805dad4aa386aeae0f72512895bd238678d37a5
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 (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d))
291    ID->addAttr(new IBOutletAttr());
292  else
293    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar);
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" << "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" << "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" << "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()) {
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" << "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" << "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" << "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
584  ObjCGCAttr::GCAttrTypes type;
585  if (Attr.getParameterName()->isStr("weak")) {
586    if (isa<FieldDecl>(d) && !isa<ObjCIvarDecl>(d))
587      S.Diag(Attr.getLoc(), diag::warn_attribute_weak_on_field);
588    type = ObjCGCAttr::Weak;
589  }
590  else if (Attr.getParameterName()->isStr("strong"))
591    type = ObjCGCAttr::Strong;
592  else {
593    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
594      << "objc_gc" << Attr.getParameterName();
595    return;
596  }
597
598  d->addAttr(new ObjCGCAttr(type));
599}
600
601static void HandleObjCNSObject(Decl *d, const AttributeList &Attr, Sema &S) {
602  if (Attr.getNumArgs() != 0) {
603    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
604    return;
605  }
606  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(d)) {
607    QualType T = TD->getUnderlyingType();
608    if (!T->isPointerType() ||
609        !T->getAsPointerType()->getPointeeType()->isRecordType()) {
610      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
611      return;
612    }
613  }
614  d->addAttr(new ObjCNSObjectAttr);
615}
616
617static void
618HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
619  if (Attr.getNumArgs() != 0) {
620    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
621    return;
622  }
623
624  if (!isa<FunctionDecl>(D)) {
625    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
626    return;
627  }
628
629  D->addAttr(new OverloadableAttr);
630}
631
632static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
633  if (!Attr.getParameterName()) {
634    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
635      << "blocks" << 1;
636    return;
637  }
638
639  if (Attr.getNumArgs() != 0) {
640    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
641    return;
642  }
643
644  BlocksAttr::BlocksAttrTypes type;
645  if (Attr.getParameterName()->isStr("byref"))
646    type = BlocksAttr::ByRef;
647  else {
648    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
649      << "blocks" << Attr.getParameterName();
650    return;
651  }
652
653  d->addAttr(new BlocksAttr(type));
654}
655
656static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
657  // check the attribute arguments.
658  if (Attr.getNumArgs() > 2) {
659    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
660      << "0, 1 or 2";
661    return;
662  }
663
664  int sentinel = 0;
665  if (Attr.getNumArgs() > 0) {
666    Expr *E = static_cast<Expr *>(Attr.getArg(0));
667    llvm::APSInt Idx(32);
668    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
669      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
670       << "sentinel" << 1 << E->getSourceRange();
671      return;
672    }
673    sentinel = Idx.getZExtValue();
674
675    if (sentinel < 0) {
676      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
677        << E->getSourceRange();
678      return;
679    }
680  }
681
682  int nullPos = 0;
683  if (Attr.getNumArgs() > 1) {
684    Expr *E = static_cast<Expr *>(Attr.getArg(1));
685    llvm::APSInt Idx(32);
686    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
687      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
688        << "sentinel" << 2 << E->getSourceRange();
689      return;
690    }
691    nullPos = Idx.getZExtValue();
692
693    if (nullPos > 1 || nullPos < 0) {
694      // FIXME: This error message could be improved, it would be nice
695      // to say what the bounds actually are.
696      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
697        << E->getSourceRange();
698      return;
699    }
700  }
701
702  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
703    QualType FT = FD->getType();
704    if (!FT->getAsFunctionTypeProto()->isVariadic()) {
705      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
706      return;
707    }
708  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
709    if (!MD->isVariadic()) {
710      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
711      return;
712    }
713  } else {
714    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
715      << "sentinel" << "function or method";
716    return;
717  }
718
719  // FIXME: Actually create the attribute.
720}
721
722static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
723  // check the attribute arguments.
724  if (Attr.getNumArgs() != 0) {
725    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
726    return;
727  }
728
729  d->addAttr(new WeakAttr());
730}
731
732static void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
733  // check the attribute arguments.
734  if (Attr.getNumArgs() != 0) {
735    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
736    return;
737  }
738
739  // Attribute can be applied only to functions or variables.
740  if (isa<VarDecl>(d)) {
741    d->addAttr(new DLLImportAttr());
742    return;
743  }
744
745  FunctionDecl *FD = dyn_cast<FunctionDecl>(d);
746  if (!FD) {
747    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
748      << "dllimport" << "function or variable";
749    return;
750  }
751
752  // Currently, the dllimport attribute is ignored for inlined functions.
753  // Warning is emitted.
754  if (FD->isInline()) {
755    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
756    return;
757  }
758
759  // The attribute is also overridden by a subsequent declaration as dllexport.
760  // Warning is emitted.
761  for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
762       nextAttr = nextAttr->getNext()) {
763    if (nextAttr->getKind() == AttributeList::AT_dllexport) {
764      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
765      return;
766    }
767  }
768
769  if (d->getAttr<DLLExportAttr>()) {
770    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
771    return;
772  }
773
774  d->addAttr(new DLLImportAttr());
775}
776
777static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
778  // check the attribute arguments.
779  if (Attr.getNumArgs() != 0) {
780    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
781    return;
782  }
783
784  // Attribute can be applied only to functions or variables.
785  if (isa<VarDecl>(d)) {
786    d->addAttr(new DLLExportAttr());
787    return;
788  }
789
790  FunctionDecl *FD = dyn_cast<FunctionDecl>(d);
791  if (!FD) {
792    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
793      << "dllexport" << "function or variable";
794    return;
795  }
796
797  // Currently, the dllexport attribute is ignored for inlined functions,
798  // unless the -fkeep-inline-functions flag has been used. Warning is emitted;
799  if (FD->isInline()) {
800    // FIXME: ... unless the -fkeep-inline-functions flag has been used.
801    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
802    return;
803  }
804
805  d->addAttr(new DLLExportAttr());
806}
807
808static void HandleSectionAttr(Decl *d, const AttributeList &Attr, Sema &S) {
809  // Attribute has no arguments.
810  if (Attr.getNumArgs() != 1) {
811    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
812    return;
813  }
814
815  // Make sure that there is a string literal as the sections's single
816  // argument.
817  StringLiteral *SE =
818    dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0)));
819  if (!SE) {
820    // FIXME
821    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
822    return;
823  }
824  d->addAttr(new SectionAttr(std::string(SE->getStrData(),
825                                         SE->getByteLength())));
826}
827
828static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
829  // Attribute has no arguments.
830  if (Attr.getNumArgs() != 0) {
831    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
832    return;
833  }
834
835  // Attribute can be applied only to functions.
836  if (!isa<FunctionDecl>(d)) {
837    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
838      << "stdcall" << "function";
839    return;
840  }
841
842  // stdcall and fastcall attributes are mutually incompatible.
843  if (d->getAttr<FastCallAttr>()) {
844    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
845      << "stdcall" << "fastcall";
846    return;
847  }
848
849  d->addAttr(new StdCallAttr());
850}
851
852static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
853  // Attribute has no arguments.
854  if (Attr.getNumArgs() != 0) {
855    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
856    return;
857  }
858
859  if (!isa<FunctionDecl>(d)) {
860    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
861      << "fastcall" << "function";
862    return;
863  }
864
865  // stdcall and fastcall attributes are mutually incompatible.
866  if (d->getAttr<StdCallAttr>()) {
867    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
868      << "fastcall" << "stdcall";
869    return;
870  }
871
872  d->addAttr(new FastCallAttr());
873}
874
875static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
876  // check the attribute arguments.
877  if (Attr.getNumArgs() != 0) {
878    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
879    return;
880  }
881
882  d->addAttr(new NoThrowAttr());
883}
884
885static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
886  // check the attribute arguments.
887  if (Attr.getNumArgs() != 0) {
888    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
889    return;
890  }
891
892  d->addAttr(new ConstAttr());
893}
894
895static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
896  // check the attribute arguments.
897  if (Attr.getNumArgs() != 0) {
898    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
899    return;
900  }
901
902  d->addAttr(new PureAttr());
903}
904
905static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
906  // Match gcc which ignores cleanup attrs when compiling C++.
907  if (S.getLangOptions().CPlusPlus)
908    return;
909
910  if (!Attr.getParameterName()) {
911    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
912    return;
913  }
914
915  if (Attr.getNumArgs() != 0) {
916    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
917    return;
918  }
919
920  VarDecl *VD = dyn_cast<VarDecl>(d);
921
922  if (!VD || !VD->hasLocalStorage()) {
923    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
924    return;
925  }
926
927  // Look up the function
928  NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
929                                        Sema::LookupOrdinaryName);
930  if (!CleanupDecl) {
931    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
932      Attr.getParameterName();
933    return;
934  }
935
936  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
937  if (!FD) {
938    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
939      Attr.getParameterName();
940    return;
941  }
942
943  if (FD->getNumParams() != 1) {
944    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
945      Attr.getParameterName();
946    return;
947  }
948
949  // We're currently more strict than GCC about what function types we accept.
950  // If this ever proves to be a problem it should be easy to fix.
951  QualType Ty = S.Context.getPointerType(VD->getType());
952  QualType ParamTy = FD->getParamDecl(0)->getType();
953  if (Ty != ParamTy) {
954    S.Diag(Attr.getLoc(),
955           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
956      Attr.getParameterName() << ParamTy << Ty;
957    return;
958  }
959
960  d->addAttr(new CleanupAttr(FD));
961}
962
963/// Handle __attribute__((format(type,idx,firstarg))) attributes
964/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
965static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
966
967  if (!Attr.getParameterName()) {
968    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
969      << "format" << 1;
970    return;
971  }
972
973  if (Attr.getNumArgs() != 2) {
974    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
975    return;
976  }
977
978  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
979    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
980      << "format" << "function";
981    return;
982  }
983
984  // FIXME: in C++ the implicit 'this' function parameter also counts.
985  // this is needed in order to be compatible with GCC
986  // the index must start in 1 and the limit is numargs+1
987  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
988  unsigned FirstIdx = 1;
989
990  const char *Format = Attr.getParameterName()->getName();
991  unsigned FormatLen = Attr.getParameterName()->getLength();
992
993  // Normalize the argument, __foo__ becomes foo.
994  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
995      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
996    Format += 2;
997    FormatLen -= 4;
998  }
999
1000  bool Supported = false;
1001  bool is_NSString = false;
1002  bool is_strftime = false;
1003  bool is_CFString = false;
1004
1005  switch (FormatLen) {
1006  default: break;
1007  case 5: Supported = !memcmp(Format, "scanf", 5); break;
1008  case 6: Supported = !memcmp(Format, "printf", 6); break;
1009  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
1010  case 8:
1011    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
1012                (is_NSString = !memcmp(Format, "NSString", 8)) ||
1013                (is_CFString = !memcmp(Format, "CFString", 8));
1014    break;
1015  }
1016
1017  if (!Supported) {
1018    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1019      << "format" << Attr.getParameterName()->getName();
1020    return;
1021  }
1022
1023  // checks for the 2nd argument
1024  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1025  llvm::APSInt Idx(32);
1026  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1027    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1028      << "format" << 2 << IdxExpr->getSourceRange();
1029    return;
1030  }
1031
1032  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1033    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1034      << "format" << 2 << IdxExpr->getSourceRange();
1035    return;
1036  }
1037
1038  // FIXME: Do we need to bounds check?
1039  unsigned ArgIdx = Idx.getZExtValue() - 1;
1040
1041  // make sure the format string is really a string
1042  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1043
1044  if (is_CFString) {
1045    if (!isCFStringType(Ty, S.Context)) {
1046      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1047        << "a CFString" << IdxExpr->getSourceRange();
1048      return;
1049    }
1050  } else if (is_NSString) {
1051    // FIXME: do we need to check if the type is NSString*?  What are
1052    //  the semantics?
1053    if (!isNSStringType(Ty, S.Context)) {
1054      // FIXME: Should highlight the actual expression that has the
1055      // wrong type.
1056      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1057        << "an NSString" << IdxExpr->getSourceRange();
1058      return;
1059    }
1060  } else if (!Ty->isPointerType() ||
1061             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
1062    // FIXME: Should highlight the actual expression that has the
1063    // wrong type.
1064    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1065      << "a string type" << IdxExpr->getSourceRange();
1066    return;
1067  }
1068
1069  // check the 3rd argument
1070  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1071  llvm::APSInt FirstArg(32);
1072  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1073    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1074      << "format" << 3 << FirstArgExpr->getSourceRange();
1075    return;
1076  }
1077
1078  // check if the function is variadic if the 3rd argument non-zero
1079  if (FirstArg != 0) {
1080    if (isFunctionOrMethodVariadic(d)) {
1081      ++NumArgs; // +1 for ...
1082    } else {
1083      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
1084      return;
1085    }
1086  }
1087
1088  // strftime requires FirstArg to be 0 because it doesn't read from any
1089  // variable the input is just the current time + the format string.
1090  if (is_strftime) {
1091    if (FirstArg != 0) {
1092      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1093        << FirstArgExpr->getSourceRange();
1094      return;
1095    }
1096  // if 0 it disables parameter checking (to use with e.g. va_list)
1097  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1098    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1099      << "format" << 3 << FirstArgExpr->getSourceRange();
1100    return;
1101  }
1102
1103  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
1104                            Idx.getZExtValue(), FirstArg.getZExtValue()));
1105}
1106
1107static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
1108                                       Sema &S) {
1109  // check the attribute arguments.
1110  if (Attr.getNumArgs() != 0) {
1111    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1112    return;
1113  }
1114
1115  // FIXME: This shouldn't be restricted to typedefs
1116  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
1117  if (!TD || !TD->getUnderlyingType()->isUnionType()) {
1118    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1119      << "transparent_union" << "union";
1120    return;
1121  }
1122
1123  RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
1124
1125  // FIXME: Should we do a check for RD->isDefinition()?
1126
1127  // FIXME: This isn't supposed to be restricted to pointers, but otherwise
1128  // we might silently generate incorrect code; see following code
1129  for (RecordDecl::field_iterator Field = RD->field_begin(),
1130                               FieldEnd = RD->field_end();
1131       Field != FieldEnd; ++Field) {
1132    if (!Field->getType()->isPointerType()) {
1133      S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer);
1134      return;
1135    }
1136  }
1137
1138  // FIXME: This is a complete hack; we should be properly propagating
1139  // transparent_union through Sema.  That said, this is close enough to
1140  // correctly compile all the common cases of transparent_union without
1141  // errors or warnings
1142  QualType NewTy = S.Context.VoidPtrTy;
1143  NewTy.addConst();
1144  TD->setUnderlyingType(NewTy);
1145}
1146
1147static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1148  // check the attribute arguments.
1149  if (Attr.getNumArgs() != 1) {
1150    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1151    return;
1152  }
1153  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
1154  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
1155
1156  // Make sure that there is a string literal as the annotation's single
1157  // argument.
1158  if (!SE) {
1159    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
1160    return;
1161  }
1162  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
1163                                          SE->getByteLength())));
1164}
1165
1166static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1167  // check the attribute arguments.
1168  if (Attr.getNumArgs() > 1) {
1169    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1170    return;
1171  }
1172
1173  unsigned Align = 0;
1174  if (Attr.getNumArgs() == 0) {
1175    // FIXME: This should be the target specific maximum alignment.
1176    // (For now we just use 128 bits which is the maximum on X86.
1177    Align = 128;
1178    return;
1179  }
1180
1181  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
1182  llvm::APSInt Alignment(32);
1183  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1184    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1185      << "aligned" << alignmentExpr->getSourceRange();
1186    return;
1187  }
1188  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
1189}
1190
1191/// HandleModeAttr - This attribute modifies the width of a decl with
1192/// primitive type.
1193///
1194/// Despite what would be logical, the mode attribute is a decl attribute,
1195/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
1196/// 'G' be HImode, not an intermediate pointer.
1197///
1198static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1199  // This attribute isn't documented, but glibc uses it.  It changes
1200  // the width of an int or unsigned int to the specified size.
1201
1202  // Check that there aren't any arguments
1203  if (Attr.getNumArgs() != 0) {
1204    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1205    return;
1206  }
1207
1208  IdentifierInfo *Name = Attr.getParameterName();
1209  if (!Name) {
1210    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1211    return;
1212  }
1213  const char *Str = Name->getName();
1214  unsigned Len = Name->getLength();
1215
1216  // Normalize the attribute name, __foo__ becomes foo.
1217  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
1218      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
1219    Str += 2;
1220    Len -= 4;
1221  }
1222
1223  unsigned DestWidth = 0;
1224  bool IntegerMode = true;
1225  switch (Len) {
1226  case 2:
1227    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
1228    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
1229    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
1230    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
1231    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
1232    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
1233    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
1234    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
1235    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
1236    break;
1237  case 4:
1238    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1239    // pointer on PIC16 and other embedded platforms.
1240    if (!memcmp(Str, "word", 4))
1241      DestWidth = S.Context.Target.getPointerWidth(0);
1242    if (!memcmp(Str, "byte", 4))
1243      DestWidth = S.Context.Target.getCharWidth();
1244    break;
1245  case 7:
1246    if (!memcmp(Str, "pointer", 7))
1247      DestWidth = S.Context.Target.getPointerWidth(0);
1248    break;
1249  }
1250
1251  QualType OldTy;
1252  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1253    OldTy = TD->getUnderlyingType();
1254  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1255    OldTy = VD->getType();
1256  else {
1257    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1258      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1259    return;
1260  }
1261
1262  // FIXME: Sync this with InitializePredefinedMacros; we need to match
1263  // int8_t and friends, at least with glibc.
1264  // FIXME: Make sure 32/64-bit integers don't get defined to types of
1265  // the wrong width on unusual platforms.
1266  // FIXME: Make sure floating-point mappings are accurate
1267  // FIXME: Support XF and TF types
1268  QualType NewTy;
1269  switch (DestWidth) {
1270  case 0:
1271    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1272    return;
1273  default:
1274    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1275    return;
1276  case 8:
1277    assert(IntegerMode);
1278    if (OldTy->isSignedIntegerType())
1279      NewTy = S.Context.SignedCharTy;
1280    else
1281      NewTy = S.Context.UnsignedCharTy;
1282    break;
1283  case 16:
1284    assert(IntegerMode);
1285    if (OldTy->isSignedIntegerType())
1286      NewTy = S.Context.ShortTy;
1287    else
1288      NewTy = S.Context.UnsignedShortTy;
1289    break;
1290  case 32:
1291    if (!IntegerMode)
1292      NewTy = S.Context.FloatTy;
1293    else if (OldTy->isSignedIntegerType())
1294      NewTy = S.Context.IntTy;
1295    else
1296      NewTy = S.Context.UnsignedIntTy;
1297    break;
1298  case 64:
1299    if (!IntegerMode)
1300      NewTy = S.Context.DoubleTy;
1301    else if (OldTy->isSignedIntegerType())
1302      NewTy = S.Context.LongLongTy;
1303    else
1304      NewTy = S.Context.UnsignedLongLongTy;
1305    break;
1306  case 128:
1307    if (!IntegerMode) {
1308      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1309      return;
1310    }
1311    NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType());
1312  }
1313
1314  if (!OldTy->getAsBuiltinType())
1315    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
1316  else if (!(IntegerMode && OldTy->isIntegerType()) &&
1317           !(!IntegerMode && OldTy->isFloatingType())) {
1318    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1319  }
1320
1321  // Install the new type.
1322  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1323    TD->setUnderlyingType(NewTy);
1324  else
1325    cast<ValueDecl>(D)->setType(NewTy);
1326}
1327
1328static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1329  // check the attribute arguments.
1330  if (Attr.getNumArgs() > 0) {
1331    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1332    return;
1333  }
1334
1335  if (!isa<FunctionDecl>(d)) {
1336    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1337      << "nodebug" << "function";
1338    return;
1339  }
1340
1341  d->addAttr(new NodebugAttr());
1342}
1343
1344//===----------------------------------------------------------------------===//
1345// Top Level Sema Entry Points
1346//===----------------------------------------------------------------------===//
1347
1348/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1349/// the attribute applies to decls.  If the attribute is a type attribute, just
1350/// silently ignore it.
1351static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
1352  switch (Attr.getKind()) {
1353  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1354  case AttributeList::AT_address_space:
1355    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
1356    break;
1357  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
1358  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1359  case AttributeList::AT_always_inline:
1360    HandleAlwaysInlineAttr  (D, Attr, S); break;
1361  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
1362  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1363  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
1364  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1365  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
1366  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
1367  case AttributeList::AT_ext_vector_type:
1368    HandleExtVectorTypeAttr(D, Attr, S);
1369    break;
1370  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1371  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
1372  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
1373  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
1374  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
1375  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
1376  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
1377  case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
1378  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
1379  case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
1380  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
1381  case AttributeList::AT_used:        HandleUsedAttr      (D, Attr, S); break;
1382  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
1383  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
1384  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
1385  case AttributeList::AT_transparent_union:
1386    HandleTransparentUnionAttr(D, Attr, S);
1387    break;
1388  case AttributeList::AT_objc_gc:     HandleObjCGCAttr    (D, Attr, S); break;
1389  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
1390  case AttributeList::AT_nsobject:    HandleObjCNSObject  (D, Attr, S); break;
1391  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1392  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1393  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1394  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1395  case AttributeList::AT_cleanup:     HandleCleanupAttr   (D, Attr, S); break;
1396  case AttributeList::AT_nodebug:     HandleNodebugAttr   (D, Attr, S); break;
1397  case AttributeList::IgnoredAttribute:
1398    // Just ignore
1399    break;
1400  default:
1401    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1402    break;
1403  }
1404}
1405
1406/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1407/// attribute list to the specified decl, ignoring any type attributes.
1408void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
1409  while (AttrList) {
1410    ProcessDeclAttribute(D, *AttrList, *this);
1411    AttrList = AttrList->getNext();
1412  }
1413}
1414
1415
1416/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
1417/// it, apply them to D.  This is a bit tricky because PD can have attributes
1418/// specified in many different places, and we need to find and apply them all.
1419void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
1420  // Apply decl attributes from the DeclSpec if present.
1421  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
1422    ProcessDeclAttributeList(D, Attrs);
1423
1424  // Walk the declarator structure, applying decl attributes that were in a type
1425  // position to the decl itself.  This handles cases like:
1426  //   int *__attr__(x)** D;
1427  // when X is a decl attribute.
1428  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
1429    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
1430      ProcessDeclAttributeList(D, Attrs);
1431
1432  // Finally, apply any attributes on the decl itself.
1433  if (const AttributeList *Attrs = PD.getAttributes())
1434    ProcessDeclAttributeList(D, Attrs);
1435}
1436
1437