SemaDeclAttr.cpp revision 6a08469ebe3e15262733841a9c29e2e563d78ba5
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 (!isa<FunctionDecl>(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 bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
404                                     Sema &S, const char *attrName) {
405  // check the attribute arguments.
406  if (Attr.getNumArgs() != 0) {
407    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
408    return false;
409  }
410
411  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
412    ValueDecl *VD = dyn_cast<ValueDecl>(d);
413    if (VD == 0 || !VD->getType()->isBlockPointerType()) {
414      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
415        << attrName << 0 /*function*/;
416      return false;
417    }
418  }
419
420  return true;
421}
422
423static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
424  if (HandleCommonNoReturnAttr(d, Attr, S, "noreturn"))
425    d->addAttr(::new (S.Context) NoReturnAttr());
426}
427
428static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
429                                       Sema &S) {
430  if (HandleCommonNoReturnAttr(d, Attr, S, "analyzer_noreturn"))
431    d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
432}
433
434static void HandleUnusedAttr(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 (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) {
442    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
443      << "unused" << 2 /*variable and function*/;
444    return;
445  }
446
447  d->addAttr(::new (S.Context) UnusedAttr());
448}
449
450static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
451  // check the attribute arguments.
452  if (Attr.getNumArgs() != 0) {
453    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
454    return;
455  }
456
457  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
458    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
459      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
460      return;
461    }
462  } else if (!isFunctionOrMethod(d)) {
463    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
464      << "used" << 2 /*variable and function*/;
465    return;
466  }
467
468  d->addAttr(::new (S.Context) UsedAttr());
469}
470
471static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
472  // check the attribute arguments.
473  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
474    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
475      << "0 or 1";
476    return;
477  }
478
479  int priority = 65535; // FIXME: Do not hardcode such constants.
480  if (Attr.getNumArgs() > 0) {
481    Expr *E = static_cast<Expr *>(Attr.getArg(0));
482    llvm::APSInt Idx(32);
483    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
484      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
485        << "constructor" << 1 << E->getSourceRange();
486      return;
487    }
488    priority = Idx.getZExtValue();
489  }
490
491  if (!isa<FunctionDecl>(d)) {
492    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
493      << "constructor" << 0 /*function*/;
494    return;
495  }
496
497  d->addAttr(::new (S.Context) ConstructorAttr(priority));
498}
499
500static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
501  // check the attribute arguments.
502  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
503    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
504       << "0 or 1";
505    return;
506  }
507
508  int priority = 65535; // FIXME: Do not hardcode such constants.
509  if (Attr.getNumArgs() > 0) {
510    Expr *E = static_cast<Expr *>(Attr.getArg(0));
511    llvm::APSInt Idx(32);
512    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
513      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
514        << "destructor" << 1 << E->getSourceRange();
515      return;
516    }
517    priority = Idx.getZExtValue();
518  }
519
520  if (!isa<FunctionDecl>(d)) {
521    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
522      << "destructor" << 0 /*function*/;
523    return;
524  }
525
526  d->addAttr(::new (S.Context) DestructorAttr(priority));
527}
528
529static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
530  // check the attribute arguments.
531  if (Attr.getNumArgs() != 0) {
532    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
533    return;
534  }
535
536  d->addAttr(::new (S.Context) DeprecatedAttr());
537}
538
539static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
540  // check the attribute arguments.
541  if (Attr.getNumArgs() != 0) {
542    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
543    return;
544  }
545
546  d->addAttr(::new (S.Context) UnavailableAttr());
547}
548
549static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
550  // check the attribute arguments.
551  if (Attr.getNumArgs() != 1) {
552    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
553    return;
554  }
555
556  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
557  Arg = Arg->IgnoreParenCasts();
558  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
559
560  if (Str == 0 || Str->isWide()) {
561    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
562      << "visibility" << 1;
563    return;
564  }
565
566  const char *TypeStr = Str->getStrData();
567  unsigned TypeLen = Str->getByteLength();
568  VisibilityAttr::VisibilityTypes type;
569
570  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
571    type = VisibilityAttr::DefaultVisibility;
572  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
573    type = VisibilityAttr::HiddenVisibility;
574  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
575    type = VisibilityAttr::HiddenVisibility; // FIXME
576  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
577    type = VisibilityAttr::ProtectedVisibility;
578  else {
579    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
580    return;
581  }
582
583  d->addAttr(::new (S.Context) VisibilityAttr(type));
584}
585
586static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
587                                    Sema &S) {
588  if (Attr.getNumArgs() != 0) {
589    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
590    return;
591  }
592
593  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
594  if (OCI == 0) {
595    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
596    return;
597  }
598
599  D->addAttr(::new (S.Context) ObjCExceptionAttr());
600}
601
602static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
603  if (Attr.getNumArgs() != 0) {
604    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
605    return;
606  }
607  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
608    QualType T = TD->getUnderlyingType();
609    if (!T->isPointerType() ||
610        !T->getAsPointerType()->getPointeeType()->isRecordType()) {
611      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
612      return;
613    }
614  }
615  D->addAttr(::new (S.Context) ObjCNSObjectAttr());
616}
617
618static void
619HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
620  if (Attr.getNumArgs() != 0) {
621    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
622    return;
623  }
624
625  if (!isa<FunctionDecl>(D)) {
626    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
627    return;
628  }
629
630  D->addAttr(::new (S.Context) OverloadableAttr());
631}
632
633static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
634  if (!Attr.getParameterName()) {
635    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
636      << "blocks" << 1;
637    return;
638  }
639
640  if (Attr.getNumArgs() != 0) {
641    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
642    return;
643  }
644
645  BlocksAttr::BlocksAttrTypes type;
646  if (Attr.getParameterName()->isStr("byref"))
647    type = BlocksAttr::ByRef;
648  else {
649    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
650      << "blocks" << Attr.getParameterName();
651    return;
652  }
653
654  d->addAttr(::new (S.Context) BlocksAttr(type));
655}
656
657static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
658  // check the attribute arguments.
659  if (Attr.getNumArgs() > 2) {
660    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
661      << "0, 1 or 2";
662    return;
663  }
664
665  int sentinel = 0;
666  if (Attr.getNumArgs() > 0) {
667    Expr *E = static_cast<Expr *>(Attr.getArg(0));
668    llvm::APSInt Idx(32);
669    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
670      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
671       << "sentinel" << 1 << E->getSourceRange();
672      return;
673    }
674    sentinel = Idx.getZExtValue();
675
676    if (sentinel < 0) {
677      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
678        << E->getSourceRange();
679      return;
680    }
681  }
682
683  int nullPos = 0;
684  if (Attr.getNumArgs() > 1) {
685    Expr *E = static_cast<Expr *>(Attr.getArg(1));
686    llvm::APSInt Idx(32);
687    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
688      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
689        << "sentinel" << 2 << E->getSourceRange();
690      return;
691    }
692    nullPos = Idx.getZExtValue();
693
694    if (nullPos > 1 || nullPos < 0) {
695      // FIXME: This error message could be improved, it would be nice
696      // to say what the bounds actually are.
697      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
698        << E->getSourceRange();
699      return;
700    }
701  }
702
703  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
704    const FunctionType *FT = FD->getType()->getAsFunctionType();
705    assert(FT && "FunctionDecl has non-function type?");
706
707    if (isa<FunctionNoProtoType>(FT)) {
708      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
709      return;
710    }
711
712    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
713      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
714      return;
715    }
716  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
717    if (!MD->isVariadic()) {
718      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
719      return;
720    }
721  } else {
722    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
723      << "sentinel" << 3 /*function or method*/;
724    return;
725  }
726
727  // FIXME: Actually create the attribute.
728}
729
730static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
731  // check the attribute arguments.
732  if (Attr.getNumArgs() != 0) {
733    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
734    return;
735  }
736
737  // TODO: could also be applied to methods?
738  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
739  if (!Fn) {
740    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
741    << "warn_unused_result" << 0 /*function*/;
742    return;
743  }
744
745  Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
746}
747
748static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
749  // check the attribute arguments.
750  if (Attr.getNumArgs() != 0) {
751    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
752    return;
753  }
754
755  // TODO: could also be applied to methods?
756  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
757    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
758    << "weak" << 2 /*variable and function*/;
759    return;
760  }
761
762  D->addAttr(::new (S.Context) WeakAttr());
763}
764
765static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
766  // check the attribute arguments.
767  if (Attr.getNumArgs() != 0) {
768    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
769    return;
770  }
771
772  // weak_import only applies to variable & function declarations.
773  bool isDef = false;
774  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
775    isDef = (!VD->hasExternalStorage() || VD->getInit());
776  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
777    isDef = FD->getBody(S.Context);
778  } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
779    // We ignore weak import on properties and methods
780    return;
781  } else {
782    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
783    << "weak_import" << 2 /*variable and function*/;
784    return;
785  }
786
787  // Merge should handle any subsequent violations.
788  if (isDef) {
789    S.Diag(Attr.getLoc(),
790           diag::warn_attribute_weak_import_invalid_on_definition)
791      << "weak_import" << 2 /*variable and function*/;
792    return;
793  }
794
795  D->addAttr(::new (S.Context) WeakImportAttr());
796}
797
798static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
799  // check the attribute arguments.
800  if (Attr.getNumArgs() != 0) {
801    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
802    return;
803  }
804
805  // Attribute can be applied only to functions or variables.
806  if (isa<VarDecl>(D)) {
807    D->addAttr(::new (S.Context) DLLImportAttr());
808    return;
809  }
810
811  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
812  if (!FD) {
813    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
814      << "dllimport" << 2 /*variable and function*/;
815    return;
816  }
817
818  // Currently, the dllimport attribute is ignored for inlined functions.
819  // Warning is emitted.
820  if (FD->isInline()) {
821    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
822    return;
823  }
824
825  // The attribute is also overridden by a subsequent declaration as dllexport.
826  // Warning is emitted.
827  for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
828       nextAttr = nextAttr->getNext()) {
829    if (nextAttr->getKind() == AttributeList::AT_dllexport) {
830      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
831      return;
832    }
833  }
834
835  if (D->getAttr<DLLExportAttr>()) {
836    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
837    return;
838  }
839
840  D->addAttr(::new (S.Context) DLLImportAttr());
841}
842
843static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
844  // check the attribute arguments.
845  if (Attr.getNumArgs() != 0) {
846    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
847    return;
848  }
849
850  // Attribute can be applied only to functions or variables.
851  if (isa<VarDecl>(D)) {
852    D->addAttr(::new (S.Context) DLLExportAttr());
853    return;
854  }
855
856  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
857  if (!FD) {
858    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
859      << "dllexport" << 2 /*variable and function*/;
860    return;
861  }
862
863  // Currently, the dllexport attribute is ignored for inlined functions,
864  // unless the -fkeep-inline-functions flag has been used. Warning is emitted;
865  if (FD->isInline()) {
866    // FIXME: ... unless the -fkeep-inline-functions flag has been used.
867    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
868    return;
869  }
870
871  D->addAttr(::new (S.Context) DLLExportAttr());
872}
873
874static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
875  // Attribute has no arguments.
876  if (Attr.getNumArgs() != 1) {
877    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
878    return;
879  }
880
881  // Make sure that there is a string literal as the sections's single
882  // argument.
883  StringLiteral *SE =
884    dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0)));
885  if (!SE) {
886    // FIXME
887    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
888    return;
889  }
890  D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(),
891                                                     SE->getByteLength())));
892}
893
894static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
895  // Attribute has no arguments.
896  if (Attr.getNumArgs() != 0) {
897    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
898    return;
899  }
900
901  // Attribute can be applied only to functions.
902  if (!isa<FunctionDecl>(d)) {
903    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
904      << "stdcall" << 0 /*function*/;
905    return;
906  }
907
908  // stdcall and fastcall attributes are mutually incompatible.
909  if (d->getAttr<FastCallAttr>()) {
910    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
911      << "stdcall" << "fastcall";
912    return;
913  }
914
915  d->addAttr(::new (S.Context) StdCallAttr());
916}
917
918static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
919  // Attribute has no arguments.
920  if (Attr.getNumArgs() != 0) {
921    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
922    return;
923  }
924
925  if (!isa<FunctionDecl>(d)) {
926    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
927      << "fastcall" << 0 /*function*/;
928    return;
929  }
930
931  // stdcall and fastcall attributes are mutually incompatible.
932  if (d->getAttr<StdCallAttr>()) {
933    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
934      << "fastcall" << "stdcall";
935    return;
936  }
937
938  d->addAttr(::new (S.Context) FastCallAttr());
939}
940
941static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
942  // check the attribute arguments.
943  if (Attr.getNumArgs() != 0) {
944    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
945    return;
946  }
947
948  d->addAttr(::new (S.Context) NoThrowAttr());
949}
950
951static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
952  // check the attribute arguments.
953  if (Attr.getNumArgs() != 0) {
954    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
955    return;
956  }
957
958  d->addAttr(::new (S.Context) ConstAttr());
959}
960
961static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
962  // check the attribute arguments.
963  if (Attr.getNumArgs() != 0) {
964    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
965    return;
966  }
967
968  d->addAttr(::new (S.Context) PureAttr());
969}
970
971static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
972  // Match gcc which ignores cleanup attrs when compiling C++.
973  if (S.getLangOptions().CPlusPlus)
974    return;
975
976  if (!Attr.getParameterName()) {
977    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
978    return;
979  }
980
981  if (Attr.getNumArgs() != 0) {
982    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
983    return;
984  }
985
986  VarDecl *VD = dyn_cast<VarDecl>(d);
987
988  if (!VD || !VD->hasLocalStorage()) {
989    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
990    return;
991  }
992
993  // Look up the function
994  NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
995                                        Sema::LookupOrdinaryName);
996  if (!CleanupDecl) {
997    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
998      Attr.getParameterName();
999    return;
1000  }
1001
1002  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1003  if (!FD) {
1004    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
1005      Attr.getParameterName();
1006    return;
1007  }
1008
1009  if (FD->getNumParams() != 1) {
1010    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
1011      Attr.getParameterName();
1012    return;
1013  }
1014
1015  // We're currently more strict than GCC about what function types we accept.
1016  // If this ever proves to be a problem it should be easy to fix.
1017  QualType Ty = S.Context.getPointerType(VD->getType());
1018  QualType ParamTy = FD->getParamDecl(0)->getType();
1019  if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
1020    S.Diag(Attr.getLoc(),
1021           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
1022      Attr.getParameterName() << ParamTy << Ty;
1023    return;
1024  }
1025
1026  d->addAttr(::new (S.Context) CleanupAttr(FD));
1027}
1028
1029/// Handle __attribute__((format(type,idx,firstarg))) attributes
1030/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1031static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1032
1033  if (!Attr.getParameterName()) {
1034    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1035      << "format" << 1;
1036    return;
1037  }
1038
1039  if (Attr.getNumArgs() != 2) {
1040    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
1041    return;
1042  }
1043
1044  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
1045    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1046      << "format" << 0 /*function*/;
1047    return;
1048  }
1049
1050  // FIXME: in C++ the implicit 'this' function parameter also counts.
1051  // this is needed in order to be compatible with GCC
1052  // the index must start in 1 and the limit is numargs+1
1053  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
1054  unsigned FirstIdx = 1;
1055
1056  const char *Format = Attr.getParameterName()->getName();
1057  unsigned FormatLen = Attr.getParameterName()->getLength();
1058
1059  // Normalize the argument, __foo__ becomes foo.
1060  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
1061      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
1062    Format += 2;
1063    FormatLen -= 4;
1064  }
1065
1066  bool Supported = false;
1067  bool is_NSString = false;
1068  bool is_strftime = false;
1069  bool is_CFString = false;
1070
1071  switch (FormatLen) {
1072  default: break;
1073  case 5: Supported = !memcmp(Format, "scanf", 5); break;
1074  case 6: Supported = !memcmp(Format, "printf", 6); break;
1075  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
1076  case 8:
1077    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
1078                (is_NSString = !memcmp(Format, "NSString", 8)) ||
1079                (is_CFString = !memcmp(Format, "CFString", 8));
1080    break;
1081  }
1082
1083  if (!Supported) {
1084    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1085      << "format" << Attr.getParameterName()->getName();
1086    return;
1087  }
1088
1089  // checks for the 2nd argument
1090  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1091  llvm::APSInt Idx(32);
1092  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1093    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1094      << "format" << 2 << IdxExpr->getSourceRange();
1095    return;
1096  }
1097
1098  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1099    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1100      << "format" << 2 << IdxExpr->getSourceRange();
1101    return;
1102  }
1103
1104  // FIXME: Do we need to bounds check?
1105  unsigned ArgIdx = Idx.getZExtValue() - 1;
1106
1107  // make sure the format string is really a string
1108  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1109
1110  if (is_CFString) {
1111    if (!isCFStringType(Ty, S.Context)) {
1112      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1113        << "a CFString" << IdxExpr->getSourceRange();
1114      return;
1115    }
1116  } else if (is_NSString) {
1117    // FIXME: do we need to check if the type is NSString*?  What are
1118    //  the semantics?
1119    if (!isNSStringType(Ty, S.Context)) {
1120      // FIXME: Should highlight the actual expression that has the
1121      // wrong type.
1122      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1123        << "an NSString" << IdxExpr->getSourceRange();
1124      return;
1125    }
1126  } else if (!Ty->isPointerType() ||
1127             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
1128    // FIXME: Should highlight the actual expression that has the
1129    // wrong type.
1130    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1131      << "a string type" << IdxExpr->getSourceRange();
1132    return;
1133  }
1134
1135  // check the 3rd argument
1136  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1137  llvm::APSInt FirstArg(32);
1138  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1139    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1140      << "format" << 3 << FirstArgExpr->getSourceRange();
1141    return;
1142  }
1143
1144  // check if the function is variadic if the 3rd argument non-zero
1145  if (FirstArg != 0) {
1146    if (isFunctionOrMethodVariadic(d)) {
1147      ++NumArgs; // +1 for ...
1148    } else {
1149      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
1150      return;
1151    }
1152  }
1153
1154  // strftime requires FirstArg to be 0 because it doesn't read from any
1155  // variable the input is just the current time + the format string.
1156  if (is_strftime) {
1157    if (FirstArg != 0) {
1158      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1159        << FirstArgExpr->getSourceRange();
1160      return;
1161    }
1162  // if 0 it disables parameter checking (to use with e.g. va_list)
1163  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1164    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1165      << "format" << 3 << FirstArgExpr->getSourceRange();
1166    return;
1167  }
1168
1169  d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen),
1170                            Idx.getZExtValue(), FirstArg.getZExtValue()));
1171}
1172
1173static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
1174                                       Sema &S) {
1175  // check the attribute arguments.
1176  if (Attr.getNumArgs() != 0) {
1177    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1178    return;
1179  }
1180
1181  // Try to find the underlying union declaration.
1182  RecordDecl *RD = 0;
1183  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
1184  if (TD && TD->getUnderlyingType()->isUnionType())
1185    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
1186  else
1187    RD = dyn_cast<RecordDecl>(d);
1188
1189  if (!RD || !RD->isUnion()) {
1190    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1191      << "transparent_union" << 1 /*union*/;
1192    return;
1193  }
1194
1195  if (!RD->isDefinition()) {
1196    S.Diag(Attr.getLoc(),
1197        diag::warn_transparent_union_attribute_not_definition);
1198    return;
1199  }
1200
1201  RecordDecl::field_iterator Field = RD->field_begin(S.Context),
1202                          FieldEnd = RD->field_end(S.Context);
1203  if (Field == FieldEnd) {
1204    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
1205    return;
1206  }
1207
1208  FieldDecl *FirstField = *Field;
1209  QualType FirstType = FirstField->getType();
1210  if (FirstType->isFloatingType() || FirstType->isVectorType()) {
1211    S.Diag(FirstField->getLocation(),
1212           diag::warn_transparent_union_attribute_floating);
1213    return;
1214  }
1215
1216  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
1217  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
1218  for (; Field != FieldEnd; ++Field) {
1219    QualType FieldType = Field->getType();
1220    if (S.Context.getTypeSize(FieldType) != FirstSize ||
1221        S.Context.getTypeAlign(FieldType) != FirstAlign) {
1222      // Warn if we drop the attribute.
1223      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1224      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
1225                                 : S.Context.getTypeAlign(FieldType);
1226      S.Diag(Field->getLocation(),
1227          diag::warn_transparent_union_attribute_field_size_align)
1228        << isSize << Field->getDeclName() << FieldBits;
1229      unsigned FirstBits = isSize? FirstSize : FirstAlign;
1230      S.Diag(FirstField->getLocation(),
1231             diag::note_transparent_union_first_field_size_align)
1232        << isSize << FirstBits;
1233      return;
1234    }
1235  }
1236
1237  RD->addAttr(::new (S.Context) TransparentUnionAttr());
1238}
1239
1240static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1241  // check the attribute arguments.
1242  if (Attr.getNumArgs() != 1) {
1243    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1244    return;
1245  }
1246  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
1247  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
1248
1249  // Make sure that there is a string literal as the annotation's single
1250  // argument.
1251  if (!SE) {
1252    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
1253    return;
1254  }
1255  d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
1256                                                        SE->getByteLength())));
1257}
1258
1259static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1260  // check the attribute arguments.
1261  if (Attr.getNumArgs() > 1) {
1262    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1263    return;
1264  }
1265
1266  unsigned Align = 0;
1267  if (Attr.getNumArgs() == 0) {
1268    // FIXME: This should be the target specific maximum alignment.
1269    // (For now we just use 128 bits which is the maximum on X86).
1270    Align = 128;
1271    d->addAttr(::new (S.Context) AlignedAttr(Align));
1272    return;
1273  }
1274
1275  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
1276  llvm::APSInt Alignment(32);
1277  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1278    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1279      << "aligned" << alignmentExpr->getSourceRange();
1280    return;
1281  }
1282  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
1283    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
1284      << alignmentExpr->getSourceRange();
1285    return;
1286  }
1287
1288  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
1289}
1290
1291/// HandleModeAttr - This attribute modifies the width of a decl with
1292/// primitive type.
1293///
1294/// Despite what would be logical, the mode attribute is a decl attribute,
1295/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
1296/// 'G' be HImode, not an intermediate pointer.
1297///
1298static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1299  // This attribute isn't documented, but glibc uses it.  It changes
1300  // the width of an int or unsigned int to the specified size.
1301
1302  // Check that there aren't any arguments
1303  if (Attr.getNumArgs() != 0) {
1304    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1305    return;
1306  }
1307
1308  IdentifierInfo *Name = Attr.getParameterName();
1309  if (!Name) {
1310    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1311    return;
1312  }
1313  const char *Str = Name->getName();
1314  unsigned Len = Name->getLength();
1315
1316  // Normalize the attribute name, __foo__ becomes foo.
1317  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
1318      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
1319    Str += 2;
1320    Len -= 4;
1321  }
1322
1323  unsigned DestWidth = 0;
1324  bool IntegerMode = true;
1325  bool ComplexMode = false;
1326  switch (Len) {
1327  case 2:
1328    switch (Str[0]) {
1329    case 'Q': DestWidth = 8; break;
1330    case 'H': DestWidth = 16; break;
1331    case 'S': DestWidth = 32; break;
1332    case 'D': DestWidth = 64; break;
1333    case 'X': DestWidth = 96; break;
1334    case 'T': DestWidth = 128; break;
1335    }
1336    if (Str[1] == 'F') {
1337      IntegerMode = false;
1338    } else if (Str[1] == 'C') {
1339      IntegerMode = false;
1340      ComplexMode = true;
1341    } else if (Str[1] != 'I') {
1342      DestWidth = 0;
1343    }
1344    break;
1345  case 4:
1346    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1347    // pointer on PIC16 and other embedded platforms.
1348    if (!memcmp(Str, "word", 4))
1349      DestWidth = S.Context.Target.getPointerWidth(0);
1350    if (!memcmp(Str, "byte", 4))
1351      DestWidth = S.Context.Target.getCharWidth();
1352    break;
1353  case 7:
1354    if (!memcmp(Str, "pointer", 7))
1355      DestWidth = S.Context.Target.getPointerWidth(0);
1356    break;
1357  }
1358
1359  QualType OldTy;
1360  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1361    OldTy = TD->getUnderlyingType();
1362  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1363    OldTy = VD->getType();
1364  else {
1365    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1366      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1367    return;
1368  }
1369
1370  if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType())
1371    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
1372  else if (IntegerMode) {
1373    if (!OldTy->isIntegralType())
1374      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1375  } else if (ComplexMode) {
1376    if (!OldTy->isComplexType())
1377      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1378  } else {
1379    if (!OldTy->isFloatingType())
1380      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1381  }
1382
1383  // FIXME: Sync this with InitializePredefinedMacros; we need to match
1384  // int8_t and friends, at least with glibc.
1385  // FIXME: Make sure 32/64-bit integers don't get defined to types of
1386  // the wrong width on unusual platforms.
1387  // FIXME: Make sure floating-point mappings are accurate
1388  // FIXME: Support XF and TF types
1389  QualType NewTy;
1390  switch (DestWidth) {
1391  case 0:
1392    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1393    return;
1394  default:
1395    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1396    return;
1397  case 8:
1398    if (!IntegerMode) {
1399      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1400      return;
1401    }
1402    if (OldTy->isSignedIntegerType())
1403      NewTy = S.Context.SignedCharTy;
1404    else
1405      NewTy = S.Context.UnsignedCharTy;
1406    break;
1407  case 16:
1408    if (!IntegerMode) {
1409      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1410      return;
1411    }
1412    if (OldTy->isSignedIntegerType())
1413      NewTy = S.Context.ShortTy;
1414    else
1415      NewTy = S.Context.UnsignedShortTy;
1416    break;
1417  case 32:
1418    if (!IntegerMode)
1419      NewTy = S.Context.FloatTy;
1420    else if (OldTy->isSignedIntegerType())
1421      NewTy = S.Context.IntTy;
1422    else
1423      NewTy = S.Context.UnsignedIntTy;
1424    break;
1425  case 64:
1426    if (!IntegerMode)
1427      NewTy = S.Context.DoubleTy;
1428    else if (OldTy->isSignedIntegerType())
1429      NewTy = S.Context.LongLongTy;
1430    else
1431      NewTy = S.Context.UnsignedLongLongTy;
1432    break;
1433  case 96:
1434    NewTy = S.Context.LongDoubleTy;
1435    break;
1436  case 128:
1437    if (!IntegerMode) {
1438      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1439      return;
1440    }
1441    NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType());
1442    break;
1443  }
1444
1445  if (ComplexMode) {
1446    NewTy = S.Context.getComplexType(NewTy);
1447  }
1448
1449  // Install the new type.
1450  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1451    TD->setUnderlyingType(NewTy);
1452  else
1453    cast<ValueDecl>(D)->setType(NewTy);
1454}
1455
1456static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1457  // check the attribute arguments.
1458  if (Attr.getNumArgs() > 0) {
1459    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1460    return;
1461  }
1462
1463  if (!isFunctionOrMethod(d)) {
1464    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1465      << "nodebug" << 0 /*function*/;
1466    return;
1467  }
1468
1469  d->addAttr(::new (S.Context) NodebugAttr());
1470}
1471
1472static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1473  // check the attribute arguments.
1474  if (Attr.getNumArgs() != 0) {
1475    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1476    return;
1477  }
1478
1479  if (!isa<FunctionDecl>(d)) {
1480    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1481    << "noinline" << 0 /*function*/;
1482    return;
1483  }
1484
1485  d->addAttr(::new (S.Context) NoinlineAttr());
1486}
1487
1488static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1489  // check the attribute arguments.
1490  if (Attr.getNumArgs() != 0) {
1491    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1492    return;
1493  }
1494
1495  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
1496  if (Fn == 0) {
1497    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1498      << "gnu_inline" << 0 /*function*/;
1499    return;
1500  }
1501
1502  if (!Fn->isInline()) {
1503    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
1504    return;
1505  }
1506
1507  d->addAttr(::new (S.Context) GNUInlineAttr());
1508}
1509
1510static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1511  // check the attribute arguments.
1512  if (Attr.getNumArgs() != 1) {
1513    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1514    return;
1515  }
1516
1517  if (!isFunctionOrMethod(d)) {
1518    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1519    << "regparm" << 0 /*function*/;
1520    return;
1521  }
1522
1523  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
1524  llvm::APSInt NumParams(32);
1525  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
1526    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1527      << "regparm" << NumParamsExpr->getSourceRange();
1528    return;
1529  }
1530
1531  if (S.Context.Target.getRegParmMax() == 0) {
1532    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
1533      << NumParamsExpr->getSourceRange();
1534    return;
1535  }
1536
1537  if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
1538    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
1539      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
1540    return;
1541  }
1542
1543  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
1544}
1545
1546//===----------------------------------------------------------------------===//
1547// Checker-specific attribute handlers.
1548//===----------------------------------------------------------------------===//
1549
1550static void HandleNSOwnershipReturnsAttr(Decl *d, const AttributeList &Attr,
1551                                           Sema &S) {
1552
1553  if (!isa<ObjCMethodDecl>(d) && !isa<FunctionDecl>(d)) {
1554    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1555      "ns_returns_ownership" << 3 /* function or method */;
1556    return;
1557  }
1558
1559  d->addAttr(::new (S.Context) NSOwnershipReturnsAttr());
1560}
1561
1562static void HandleNSOwnershipAttr(Decl *d, const AttributeList &Attr,
1563                                    Sema &S, bool attachToMethodDecl = false) {
1564
1565  if (!isa<ParmVarDecl>(d) && (!attachToMethodDecl || !isa<ObjCMethodDecl>(d))){
1566    const char *name;
1567
1568    switch (Attr.getKind()) {
1569      default:
1570        assert(0 && "invalid ownership attribute");
1571        return;
1572      case AttributeList::AT_cf_ownership_release:
1573        name = "cf_ownership_release"; break;
1574      case AttributeList::AT_cf_ownership_retain:
1575        name = "cf_ownership_retain"; break;
1576      case AttributeList::AT_ns_ownership_release:
1577        name = "ns_ownership_release"; break;
1578      case AttributeList::AT_ns_ownership_retain:
1579        name = "ns_ownership_retain"; break;
1580    };
1581
1582    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << name
1583      << (attachToMethodDecl ? 5 /* parameter or method decl */
1584                             : 4 /* parameter */);
1585    return;
1586  }
1587
1588  switch (Attr.getKind()) {
1589    default:
1590      assert(0 && "invalid ownership attribute");
1591      return;
1592    case AttributeList::AT_cf_ownership_release:
1593      d->addAttr(::new (S.Context) CFOwnershipReleaseAttr()); return;
1594    case AttributeList::AT_cf_ownership_retain:
1595      d->addAttr(::new (S.Context) CFOwnershipRetainAttr()); return;
1596    case AttributeList::AT_ns_ownership_release:
1597      d->addAttr(::new (S.Context) NSOwnershipReleaseAttr());   return;
1598    case AttributeList::AT_ns_ownership_retain:
1599      d->addAttr(::new (S.Context) NSOwnershipRetainAttr());   return;
1600  }
1601}
1602
1603//===----------------------------------------------------------------------===//
1604// Top Level Sema Entry Points
1605//===----------------------------------------------------------------------===//
1606
1607/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1608/// the attribute applies to decls.  If the attribute is a type attribute, just
1609/// silently ignore it.
1610static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
1611  switch (Attr.getKind()) {
1612  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1613  case AttributeList::AT_address_space:
1614  case AttributeList::AT_objc_gc:
1615    // Ignore these, these are type attributes, handled by ProcessTypeAttributes.
1616    break;
1617  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
1618  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1619  case AttributeList::AT_always_inline:
1620    HandleAlwaysInlineAttr  (D, Attr, S); break;
1621  case AttributeList::AT_analyzer_noreturn:
1622    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
1623  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
1624  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1625  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
1626  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1627  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
1628  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
1629  case AttributeList::AT_ext_vector_type:
1630    HandleExtVectorTypeAttr(D, Attr, S);
1631    break;
1632  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1633  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
1634  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr(D, Attr, S); break;
1635  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
1636  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
1637  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
1638  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
1639
1640  // Checker-specific.
1641  case AttributeList::AT_cf_ownership_release:
1642  case AttributeList::AT_cf_ownership_retain:
1643      HandleNSOwnershipAttr(D, Attr, S); break;
1644  case AttributeList::AT_ns_ownership_release:
1645  case AttributeList::AT_ns_ownership_retain:
1646      HandleNSOwnershipAttr(D, Attr, S, true); break;
1647  case AttributeList::AT_ns_returns_ownership:
1648    HandleNSOwnershipReturnsAttr(D, Attr, S); break;
1649
1650  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
1651  case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
1652  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
1653  case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
1654  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
1655  case AttributeList::AT_used:        HandleUsedAttr      (D, Attr, S); break;
1656  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
1657  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
1658  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
1659    break;
1660  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
1661  case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break;
1662  case AttributeList::AT_transparent_union:
1663    HandleTransparentUnionAttr(D, Attr, S);
1664    break;
1665  case AttributeList::AT_objc_exception:
1666    HandleObjCExceptionAttr(D, Attr, S);
1667    break;
1668  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
1669  case AttributeList::AT_nsobject:    HandleObjCNSObject  (D, Attr, S); break;
1670  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1671  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1672  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1673  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1674  case AttributeList::AT_cleanup:     HandleCleanupAttr   (D, Attr, S); break;
1675  case AttributeList::AT_nodebug:     HandleNodebugAttr   (D, Attr, S); break;
1676  case AttributeList::AT_noinline:    HandleNoinlineAttr  (D, Attr, S); break;
1677  case AttributeList::AT_regparm:     HandleRegparmAttr   (D, Attr, S); break;
1678  case AttributeList::IgnoredAttribute:
1679  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
1680    // Just ignore
1681    break;
1682  default:
1683    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1684    break;
1685  }
1686}
1687
1688/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1689/// attribute list to the specified decl, ignoring any type attributes.
1690void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
1691  while (AttrList) {
1692    ProcessDeclAttribute(D, *AttrList, *this);
1693    AttrList = AttrList->getNext();
1694  }
1695}
1696
1697/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
1698/// it, apply them to D.  This is a bit tricky because PD can have attributes
1699/// specified in many different places, and we need to find and apply them all.
1700void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
1701  // Apply decl attributes from the DeclSpec if present.
1702  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
1703    ProcessDeclAttributeList(D, Attrs);
1704
1705  // Walk the declarator structure, applying decl attributes that were in a type
1706  // position to the decl itself.  This handles cases like:
1707  //   int *__attr__(x)** D;
1708  // when X is a decl attribute.
1709  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
1710    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
1711      ProcessDeclAttributeList(D, Attrs);
1712
1713  // Finally, apply any attributes on the decl itself.
1714  if (const AttributeList *Attrs = PD.getAttributes())
1715    ProcessDeclAttributeList(D, Attrs);
1716}
1717