SemaDeclAttr.cpp revision 1102f4282ceb430dbc9fcedb9dd2ad25898a09e8
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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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 (S.Context) 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    const FunctionType *FT = FD->getType()->getAsFunctionType();
691    assert(FT && "FunctionDecl has non-function type?");
692
693    if (isa<FunctionNoProtoType>(FT)) {
694      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
695      return;
696    }
697
698    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
699      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
700      return;
701    }
702  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
703    if (!MD->isVariadic()) {
704      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
705      return;
706    }
707  } else {
708    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
709      << "sentinel" << 3 /*function or method*/;
710    return;
711  }
712
713  // FIXME: Actually create the attribute.
714}
715
716static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
717  // check the attribute arguments.
718  if (Attr.getNumArgs() != 0) {
719    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
720    return;
721  }
722
723  // TODO: could also be applied to methods?
724  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
725  if (!Fn) {
726    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
727    << "warn_unused_result" << 0 /*function*/;
728    return;
729  }
730
731  Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
732}
733
734static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
735  // check the attribute arguments.
736  if (Attr.getNumArgs() != 0) {
737    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
738    return;
739  }
740
741  // TODO: could also be applied to methods?
742  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
743    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
744    << "weak" << 2 /*variable and function*/;
745    return;
746  }
747
748  D->addAttr(::new (S.Context) WeakAttr());
749}
750
751static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
752  // check the attribute arguments.
753  if (Attr.getNumArgs() != 0) {
754    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
755    return;
756  }
757
758  // weak_import only applies to variable & function declarations.
759  bool isDef = false;
760  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
761    isDef = (!VD->hasExternalStorage() || VD->getInit());
762  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
763    isDef = FD->getBody();
764  } else if (isa<ObjCPropertyDecl>(D)) {
765    // We ignore weak import on properties
766    return;
767  } else {
768    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
769    << "weak_import" << 2 /*variable and function*/;
770    return;
771  }
772
773  // Merge should handle any subsequent violations.
774  if (isDef) {
775    S.Diag(Attr.getLoc(),
776           diag::warn_attribute_weak_import_invalid_on_definition)
777      << "weak_import" << 2 /*variable and function*/;
778    return;
779  }
780
781  D->addAttr(::new (S.Context) WeakImportAttr());
782}
783
784static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
785  // check the attribute arguments.
786  if (Attr.getNumArgs() != 0) {
787    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
788    return;
789  }
790
791  // Attribute can be applied only to functions or variables.
792  if (isa<VarDecl>(D)) {
793    D->addAttr(::new (S.Context) DLLImportAttr());
794    return;
795  }
796
797  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
798  if (!FD) {
799    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
800      << "dllimport" << 2 /*variable and function*/;
801    return;
802  }
803
804  // Currently, the dllimport attribute is ignored for inlined functions.
805  // Warning is emitted.
806  if (FD->isInline()) {
807    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
808    return;
809  }
810
811  // The attribute is also overridden by a subsequent declaration as dllexport.
812  // Warning is emitted.
813  for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
814       nextAttr = nextAttr->getNext()) {
815    if (nextAttr->getKind() == AttributeList::AT_dllexport) {
816      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
817      return;
818    }
819  }
820
821  if (D->getAttr<DLLExportAttr>()) {
822    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
823    return;
824  }
825
826  D->addAttr(::new (S.Context) DLLImportAttr());
827}
828
829static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
830  // check the attribute arguments.
831  if (Attr.getNumArgs() != 0) {
832    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
833    return;
834  }
835
836  // Attribute can be applied only to functions or variables.
837  if (isa<VarDecl>(D)) {
838    D->addAttr(::new (S.Context) DLLExportAttr());
839    return;
840  }
841
842  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
843  if (!FD) {
844    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
845      << "dllexport" << 2 /*variable and function*/;
846    return;
847  }
848
849  // Currently, the dllexport attribute is ignored for inlined functions,
850  // unless the -fkeep-inline-functions flag has been used. Warning is emitted;
851  if (FD->isInline()) {
852    // FIXME: ... unless the -fkeep-inline-functions flag has been used.
853    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
854    return;
855  }
856
857  D->addAttr(::new (S.Context) DLLExportAttr());
858}
859
860static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
861  // Attribute has no arguments.
862  if (Attr.getNumArgs() != 1) {
863    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
864    return;
865  }
866
867  // Make sure that there is a string literal as the sections's single
868  // argument.
869  StringLiteral *SE =
870    dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0)));
871  if (!SE) {
872    // FIXME
873    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
874    return;
875  }
876  D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(),
877                                                     SE->getByteLength())));
878}
879
880static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
881  // Attribute has no arguments.
882  if (Attr.getNumArgs() != 0) {
883    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
884    return;
885  }
886
887  // Attribute can be applied only to functions.
888  if (!isa<FunctionDecl>(d)) {
889    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
890      << "stdcall" << 0 /*function*/;
891    return;
892  }
893
894  // stdcall and fastcall attributes are mutually incompatible.
895  if (d->getAttr<FastCallAttr>()) {
896    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
897      << "stdcall" << "fastcall";
898    return;
899  }
900
901  d->addAttr(::new (S.Context) StdCallAttr());
902}
903
904static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
905  // Attribute has no arguments.
906  if (Attr.getNumArgs() != 0) {
907    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
908    return;
909  }
910
911  if (!isa<FunctionDecl>(d)) {
912    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
913      << "fastcall" << 0 /*function*/;
914    return;
915  }
916
917  // stdcall and fastcall attributes are mutually incompatible.
918  if (d->getAttr<StdCallAttr>()) {
919    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
920      << "fastcall" << "stdcall";
921    return;
922  }
923
924  d->addAttr(::new (S.Context) FastCallAttr());
925}
926
927static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
928  // check the attribute arguments.
929  if (Attr.getNumArgs() != 0) {
930    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
931    return;
932  }
933
934  d->addAttr(::new (S.Context) NoThrowAttr());
935}
936
937static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
938  // check the attribute arguments.
939  if (Attr.getNumArgs() != 0) {
940    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
941    return;
942  }
943
944  d->addAttr(::new (S.Context) ConstAttr());
945}
946
947static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
948  // check the attribute arguments.
949  if (Attr.getNumArgs() != 0) {
950    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
951    return;
952  }
953
954  d->addAttr(::new (S.Context) PureAttr());
955}
956
957static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
958  // Match gcc which ignores cleanup attrs when compiling C++.
959  if (S.getLangOptions().CPlusPlus)
960    return;
961
962  if (!Attr.getParameterName()) {
963    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
964    return;
965  }
966
967  if (Attr.getNumArgs() != 0) {
968    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
969    return;
970  }
971
972  VarDecl *VD = dyn_cast<VarDecl>(d);
973
974  if (!VD || !VD->hasLocalStorage()) {
975    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
976    return;
977  }
978
979  // Look up the function
980  NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
981                                        Sema::LookupOrdinaryName);
982  if (!CleanupDecl) {
983    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
984      Attr.getParameterName();
985    return;
986  }
987
988  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
989  if (!FD) {
990    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
991      Attr.getParameterName();
992    return;
993  }
994
995  if (FD->getNumParams() != 1) {
996    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
997      Attr.getParameterName();
998    return;
999  }
1000
1001  // We're currently more strict than GCC about what function types we accept.
1002  // If this ever proves to be a problem it should be easy to fix.
1003  QualType Ty = S.Context.getPointerType(VD->getType());
1004  QualType ParamTy = FD->getParamDecl(0)->getType();
1005  if (S.CheckAssignmentConstraints(Ty, ParamTy) != Sema::Compatible) {
1006    S.Diag(Attr.getLoc(),
1007           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
1008      Attr.getParameterName() << ParamTy << Ty;
1009    return;
1010  }
1011
1012  d->addAttr(::new (S.Context) CleanupAttr(FD));
1013}
1014
1015/// Handle __attribute__((format(type,idx,firstarg))) attributes
1016/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1017static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1018
1019  if (!Attr.getParameterName()) {
1020    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1021      << "format" << 1;
1022    return;
1023  }
1024
1025  if (Attr.getNumArgs() != 2) {
1026    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
1027    return;
1028  }
1029
1030  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
1031    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1032      << "format" << 0 /*function*/;
1033    return;
1034  }
1035
1036  // FIXME: in C++ the implicit 'this' function parameter also counts.
1037  // this is needed in order to be compatible with GCC
1038  // the index must start in 1 and the limit is numargs+1
1039  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
1040  unsigned FirstIdx = 1;
1041
1042  const char *Format = Attr.getParameterName()->getName();
1043  unsigned FormatLen = Attr.getParameterName()->getLength();
1044
1045  // Normalize the argument, __foo__ becomes foo.
1046  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
1047      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
1048    Format += 2;
1049    FormatLen -= 4;
1050  }
1051
1052  bool Supported = false;
1053  bool is_NSString = false;
1054  bool is_strftime = false;
1055  bool is_CFString = false;
1056
1057  switch (FormatLen) {
1058  default: break;
1059  case 5: Supported = !memcmp(Format, "scanf", 5); break;
1060  case 6: Supported = !memcmp(Format, "printf", 6); break;
1061  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
1062  case 8:
1063    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
1064                (is_NSString = !memcmp(Format, "NSString", 8)) ||
1065                (is_CFString = !memcmp(Format, "CFString", 8));
1066    break;
1067  }
1068
1069  if (!Supported) {
1070    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1071      << "format" << Attr.getParameterName()->getName();
1072    return;
1073  }
1074
1075  // checks for the 2nd argument
1076  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1077  llvm::APSInt Idx(32);
1078  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1079    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1080      << "format" << 2 << IdxExpr->getSourceRange();
1081    return;
1082  }
1083
1084  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1085    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1086      << "format" << 2 << IdxExpr->getSourceRange();
1087    return;
1088  }
1089
1090  // FIXME: Do we need to bounds check?
1091  unsigned ArgIdx = Idx.getZExtValue() - 1;
1092
1093  // make sure the format string is really a string
1094  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1095
1096  if (is_CFString) {
1097    if (!isCFStringType(Ty, S.Context)) {
1098      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1099        << "a CFString" << IdxExpr->getSourceRange();
1100      return;
1101    }
1102  } else if (is_NSString) {
1103    // FIXME: do we need to check if the type is NSString*?  What are
1104    //  the semantics?
1105    if (!isNSStringType(Ty, S.Context)) {
1106      // FIXME: Should highlight the actual expression that has the
1107      // wrong type.
1108      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1109        << "an NSString" << IdxExpr->getSourceRange();
1110      return;
1111    }
1112  } else if (!Ty->isPointerType() ||
1113             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
1114    // FIXME: Should highlight the actual expression that has the
1115    // wrong type.
1116    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1117      << "a string type" << IdxExpr->getSourceRange();
1118    return;
1119  }
1120
1121  // check the 3rd argument
1122  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1123  llvm::APSInt FirstArg(32);
1124  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1125    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1126      << "format" << 3 << FirstArgExpr->getSourceRange();
1127    return;
1128  }
1129
1130  // check if the function is variadic if the 3rd argument non-zero
1131  if (FirstArg != 0) {
1132    if (isFunctionOrMethodVariadic(d)) {
1133      ++NumArgs; // +1 for ...
1134    } else {
1135      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
1136      return;
1137    }
1138  }
1139
1140  // strftime requires FirstArg to be 0 because it doesn't read from any
1141  // variable the input is just the current time + the format string.
1142  if (is_strftime) {
1143    if (FirstArg != 0) {
1144      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1145        << FirstArgExpr->getSourceRange();
1146      return;
1147    }
1148  // if 0 it disables parameter checking (to use with e.g. va_list)
1149  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1150    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1151      << "format" << 3 << FirstArgExpr->getSourceRange();
1152    return;
1153  }
1154
1155  d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen),
1156                            Idx.getZExtValue(), FirstArg.getZExtValue()));
1157}
1158
1159static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
1160                                       Sema &S) {
1161  // check the attribute arguments.
1162  if (Attr.getNumArgs() != 0) {
1163    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1164    return;
1165  }
1166
1167  // FIXME: This shouldn't be restricted to typedefs
1168  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
1169  if (!TD || !TD->getUnderlyingType()->isUnionType()) {
1170    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1171      << "transparent_union" << 1 /*union*/;
1172    return;
1173  }
1174
1175  RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
1176
1177  // FIXME: Should we do a check for RD->isDefinition()?
1178
1179  // FIXME: This isn't supposed to be restricted to pointers, but otherwise
1180  // we might silently generate incorrect code; see following code
1181  for (RecordDecl::field_iterator Field = RD->field_begin(),
1182                               FieldEnd = RD->field_end();
1183       Field != FieldEnd; ++Field) {
1184    if (!Field->getType()->isPointerType()) {
1185      S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer);
1186      return;
1187    }
1188  }
1189
1190  // FIXME: This is a complete hack; we should be properly propagating
1191  // transparent_union through Sema.  That said, this is close enough to
1192  // correctly compile all the common cases of transparent_union without
1193  // errors or warnings
1194  QualType NewTy = S.Context.VoidPtrTy;
1195  NewTy.addConst();
1196  TD->setUnderlyingType(NewTy);
1197}
1198
1199static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1200  // check the attribute arguments.
1201  if (Attr.getNumArgs() != 1) {
1202    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1203    return;
1204  }
1205  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
1206  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
1207
1208  // Make sure that there is a string literal as the annotation's single
1209  // argument.
1210  if (!SE) {
1211    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
1212    return;
1213  }
1214  d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
1215                                                        SE->getByteLength())));
1216}
1217
1218static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1219  // check the attribute arguments.
1220  if (Attr.getNumArgs() > 1) {
1221    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1222    return;
1223  }
1224
1225  unsigned Align = 0;
1226  if (Attr.getNumArgs() == 0) {
1227    // FIXME: This should be the target specific maximum alignment.
1228    // (For now we just use 128 bits which is the maximum on X86).
1229    Align = 128;
1230    d->addAttr(::new (S.Context) AlignedAttr(Align));
1231    return;
1232  }
1233
1234  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
1235  llvm::APSInt Alignment(32);
1236  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1237    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1238      << "aligned" << alignmentExpr->getSourceRange();
1239    return;
1240  }
1241  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
1242    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
1243      << alignmentExpr->getSourceRange();
1244    return;
1245  }
1246
1247  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
1248}
1249
1250/// HandleModeAttr - This attribute modifies the width of a decl with
1251/// primitive type.
1252///
1253/// Despite what would be logical, the mode attribute is a decl attribute,
1254/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
1255/// 'G' be HImode, not an intermediate pointer.
1256///
1257static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1258  // This attribute isn't documented, but glibc uses it.  It changes
1259  // the width of an int or unsigned int to the specified size.
1260
1261  // Check that there aren't any arguments
1262  if (Attr.getNumArgs() != 0) {
1263    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1264    return;
1265  }
1266
1267  IdentifierInfo *Name = Attr.getParameterName();
1268  if (!Name) {
1269    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1270    return;
1271  }
1272  const char *Str = Name->getName();
1273  unsigned Len = Name->getLength();
1274
1275  // Normalize the attribute name, __foo__ becomes foo.
1276  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
1277      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
1278    Str += 2;
1279    Len -= 4;
1280  }
1281
1282  unsigned DestWidth = 0;
1283  bool IntegerMode = true;
1284  bool ComplexMode = false;
1285  switch (Len) {
1286  case 2:
1287    switch (Str[0]) {
1288    case 'Q': DestWidth = 8; break;
1289    case 'H': DestWidth = 16; break;
1290    case 'S': DestWidth = 32; break;
1291    case 'D': DestWidth = 64; break;
1292    case 'X': DestWidth = 96; break;
1293    case 'T': DestWidth = 128; break;
1294    }
1295    if (Str[1] == 'F') {
1296      IntegerMode = false;
1297    } else if (Str[1] == 'C') {
1298      IntegerMode = false;
1299      ComplexMode = true;
1300    } else if (Str[1] != 'I') {
1301      DestWidth = 0;
1302    }
1303    break;
1304  case 4:
1305    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1306    // pointer on PIC16 and other embedded platforms.
1307    if (!memcmp(Str, "word", 4))
1308      DestWidth = S.Context.Target.getPointerWidth(0);
1309    if (!memcmp(Str, "byte", 4))
1310      DestWidth = S.Context.Target.getCharWidth();
1311    break;
1312  case 7:
1313    if (!memcmp(Str, "pointer", 7))
1314      DestWidth = S.Context.Target.getPointerWidth(0);
1315    break;
1316  }
1317
1318  QualType OldTy;
1319  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1320    OldTy = TD->getUnderlyingType();
1321  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1322    OldTy = VD->getType();
1323  else {
1324    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1325      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1326    return;
1327  }
1328
1329  if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType())
1330    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
1331  else if (IntegerMode) {
1332    if (!OldTy->isIntegralType())
1333      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1334  } else if (ComplexMode) {
1335    if (!OldTy->isComplexType())
1336      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1337  } else {
1338    if (!OldTy->isFloatingType())
1339      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1340  }
1341
1342  // FIXME: Sync this with InitializePredefinedMacros; we need to match
1343  // int8_t and friends, at least with glibc.
1344  // FIXME: Make sure 32/64-bit integers don't get defined to types of
1345  // the wrong width on unusual platforms.
1346  // FIXME: Make sure floating-point mappings are accurate
1347  // FIXME: Support XF and TF types
1348  QualType NewTy;
1349  switch (DestWidth) {
1350  case 0:
1351    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1352    return;
1353  default:
1354    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1355    return;
1356  case 8:
1357    if (!IntegerMode) {
1358      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1359      return;
1360    }
1361    if (OldTy->isSignedIntegerType())
1362      NewTy = S.Context.SignedCharTy;
1363    else
1364      NewTy = S.Context.UnsignedCharTy;
1365    break;
1366  case 16:
1367    if (!IntegerMode) {
1368      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1369      return;
1370    }
1371    if (OldTy->isSignedIntegerType())
1372      NewTy = S.Context.ShortTy;
1373    else
1374      NewTy = S.Context.UnsignedShortTy;
1375    break;
1376  case 32:
1377    if (!IntegerMode)
1378      NewTy = S.Context.FloatTy;
1379    else if (OldTy->isSignedIntegerType())
1380      NewTy = S.Context.IntTy;
1381    else
1382      NewTy = S.Context.UnsignedIntTy;
1383    break;
1384  case 64:
1385    if (!IntegerMode)
1386      NewTy = S.Context.DoubleTy;
1387    else if (OldTy->isSignedIntegerType())
1388      NewTy = S.Context.LongLongTy;
1389    else
1390      NewTy = S.Context.UnsignedLongLongTy;
1391    break;
1392  case 96:
1393    NewTy = S.Context.LongDoubleTy;
1394    break;
1395  case 128:
1396    if (!IntegerMode) {
1397      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1398      return;
1399    }
1400    NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType());
1401    break;
1402  }
1403
1404  if (ComplexMode) {
1405    NewTy = S.Context.getComplexType(NewTy);
1406  }
1407
1408  // Install the new type.
1409  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1410    TD->setUnderlyingType(NewTy);
1411  else
1412    cast<ValueDecl>(D)->setType(NewTy);
1413}
1414
1415static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1416  // check the attribute arguments.
1417  if (Attr.getNumArgs() > 0) {
1418    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1419    return;
1420  }
1421
1422  if (!isFunctionOrMethod(d)) {
1423    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1424      << "nodebug" << 0 /*function*/;
1425    return;
1426  }
1427
1428  d->addAttr(::new (S.Context) NodebugAttr());
1429}
1430
1431static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1432  // check the attribute arguments.
1433  if (Attr.getNumArgs() != 0) {
1434    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1435    return;
1436  }
1437
1438  if (!isFunctionOrMethod(d)) {
1439    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1440    << "noinline" << 0 /*function*/;
1441    return;
1442  }
1443
1444  d->addAttr(::new (S.Context) NoinlineAttr());
1445}
1446
1447static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1448  // check the attribute arguments.
1449  if (Attr.getNumArgs() != 1) {
1450    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1451    return;
1452  }
1453
1454  if (!isFunctionOrMethod(d)) {
1455    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1456    << "regparm" << 0 /*function*/;
1457    return;
1458  }
1459
1460  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
1461  llvm::APSInt NumParams(32);
1462  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
1463    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1464      << "regparm" << NumParamsExpr->getSourceRange();
1465    return;
1466  }
1467
1468  if (S.Context.Target.getRegParmMax() == 0) {
1469    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
1470      << NumParamsExpr->getSourceRange();
1471    return;
1472  }
1473
1474  if (NumParams.getLimitedValue(4) > S.Context.Target.getRegParmMax()) {
1475    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
1476      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
1477    return;
1478  }
1479
1480  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
1481}
1482
1483//===----------------------------------------------------------------------===//
1484// Top Level Sema Entry Points
1485//===----------------------------------------------------------------------===//
1486
1487/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1488/// the attribute applies to decls.  If the attribute is a type attribute, just
1489/// silently ignore it.
1490static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
1491  switch (Attr.getKind()) {
1492  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1493  case AttributeList::AT_address_space:
1494  case AttributeList::AT_objc_gc:
1495    // Ignore these, these are type attributes, handled by ProcessTypeAttributes.
1496    break;
1497  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
1498  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1499  case AttributeList::AT_always_inline:
1500    HandleAlwaysInlineAttr  (D, Attr, S); break;
1501  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
1502  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1503  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
1504  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1505  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
1506  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
1507  case AttributeList::AT_ext_vector_type:
1508    HandleExtVectorTypeAttr(D, Attr, S);
1509    break;
1510  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1511  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
1512  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
1513  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
1514  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
1515  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
1516  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
1517  case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
1518  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
1519  case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
1520  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
1521  case AttributeList::AT_used:        HandleUsedAttr      (D, Attr, S); break;
1522  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
1523  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
1524  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
1525    break;
1526  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
1527  case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break;
1528  case AttributeList::AT_transparent_union:
1529    HandleTransparentUnionAttr(D, Attr, S);
1530    break;
1531  case AttributeList::AT_objc_exception:
1532    HandleObjCExceptionAttr(D, Attr, S);
1533    break;
1534  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
1535  case AttributeList::AT_nsobject:    HandleObjCNSObject  (D, Attr, S); break;
1536  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1537  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1538  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1539  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1540  case AttributeList::AT_cleanup:     HandleCleanupAttr   (D, Attr, S); break;
1541  case AttributeList::AT_nodebug:     HandleNodebugAttr   (D, Attr, S); break;
1542  case AttributeList::AT_noinline:    HandleNoinlineAttr  (D, Attr, S); break;
1543  case AttributeList::AT_regparm:     HandleRegparmAttr   (D, Attr, S); break;
1544  case AttributeList::IgnoredAttribute:
1545    // Just ignore
1546    break;
1547  default:
1548    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1549    break;
1550  }
1551}
1552
1553/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1554/// attribute list to the specified decl, ignoring any type attributes.
1555void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
1556  while (AttrList) {
1557    ProcessDeclAttribute(D, *AttrList, *this);
1558    AttrList = AttrList->getNext();
1559  }
1560}
1561
1562
1563/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
1564/// it, apply them to D.  This is a bit tricky because PD can have attributes
1565/// specified in many different places, and we need to find and apply them all.
1566void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
1567  // Apply decl attributes from the DeclSpec if present.
1568  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
1569    ProcessDeclAttributeList(D, Attrs);
1570
1571  // Walk the declarator structure, applying decl attributes that were in a type
1572  // position to the decl itself.  This handles cases like:
1573  //   int *__attr__(x)** D;
1574  // when X is a decl attribute.
1575  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
1576    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
1577      ProcessDeclAttributeList(D, Attrs);
1578
1579  // Finally, apply any attributes on the decl itself.
1580  if (const AttributeList *Attrs = PD.getAttributes())
1581    ProcessDeclAttributeList(D, Attrs);
1582}
1583
1584