SemaDeclAttr.cpp revision 6782fc6925a85c3772253e272745589a0c799c15
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/Diagnostic.h"
19#include "clang/Basic/TargetInfo.h"
20#include "clang/Parse/DeclSpec.h"
21#include <llvm/ADT/StringExtras.h>
22using namespace clang;
23
24//===----------------------------------------------------------------------===//
25//  Helper functions
26//===----------------------------------------------------------------------===//
27
28static const FunctionTypeProto *getFunctionProto(Decl *d) {
29  QualType Ty;
30  if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
31    Ty = decl->getType();
32  else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
33    Ty = decl->getType();
34  else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
35    Ty = decl->getUnderlyingType();
36  else
37    return 0;
38
39  if (Ty->isFunctionPointerType())
40    Ty = Ty->getAsPointerType()->getPointeeType();
41
42  if (const FunctionType *FnTy = Ty->getAsFunctionType())
43    return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType());
44
45  return 0;
46}
47
48static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
49  const PointerType *PT = T->getAsPointerType();
50  if (!PT)
51    return false;
52
53  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType();
54  if (!ClsT)
55    return false;
56
57  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
58
59  // FIXME: Should we walk the chain of classes?
60  return ClsName == &Ctx.Idents.get("NSString") ||
61         ClsName == &Ctx.Idents.get("NSMutableString");
62}
63
64//===----------------------------------------------------------------------===//
65// Attribute Implementations
66//===----------------------------------------------------------------------===//
67
68// FIXME: All this manual attribute parsing code is gross. At the
69// least add some helper functions to check most argument patterns (#
70// and types of args).
71
72static void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
73                                    Sema &S) {
74  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
75  if (tDecl == 0) {
76    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
77    return;
78  }
79
80  QualType curType = tDecl->getUnderlyingType();
81  // check the attribute arguments.
82  if (Attr.getNumArgs() != 1) {
83    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
84           std::string("1"));
85    return;
86  }
87  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
88  llvm::APSInt vecSize(32);
89  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
90    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
91           "ext_vector_type", sizeExpr->getSourceRange());
92    return;
93  }
94  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
95  // in conjunction with complex types (pointers, arrays, functions, etc.).
96  if (!curType->isIntegerType() && !curType->isRealFloatingType()) {
97    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
98           curType.getAsString());
99    return;
100  }
101  // unlike gcc's vector_size attribute, the size is specified as the
102  // number of elements, not the number of bytes.
103  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
104
105  if (vectorSize == 0) {
106    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
107           sizeExpr->getSourceRange());
108    return;
109  }
110  // Instantiate/Install the vector type, the number of elements is > 0.
111  tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize));
112  // Remember this typedef decl, we will need it later for diagnostics.
113  S.ExtVectorDecls.push_back(tDecl);
114}
115
116
117/// HandleVectorSizeAttribute - this attribute is only applicable to
118/// integral and float scalars, although arrays, pointers, and function
119/// return values are allowed in conjunction with this construct. Aggregates
120/// with this attribute are invalid, even if they are of the same size as a
121/// corresponding scalar.
122/// The raw attribute should contain precisely 1 argument, the vector size
123/// for the variable, measured in bytes. If curType and rawAttr are well
124/// formed, this routine will return a new vector type.
125static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
126  QualType CurType;
127  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
128    CurType = VD->getType();
129  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
130    CurType = TD->getUnderlyingType();
131  else {
132    S.Diag(D->getLocation(), diag::err_attr_wrong_decl,
133           std::string("vector_size"),
134           SourceRange(Attr.getLoc(), Attr.getLoc()));
135    return;
136  }
137
138  // Check the attribute arugments.
139  if (Attr.getNumArgs() != 1) {
140    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
141           std::string("1"));
142    return;
143  }
144  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
145  llvm::APSInt vecSize(32);
146  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
147    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
148           "vector_size", sizeExpr->getSourceRange());
149    return;
150  }
151  // navigate to the base type - we need to provide for vector pointers,
152  // vector arrays, and functions returning vectors.
153  if (CurType->isPointerType() || CurType->isArrayType() ||
154      CurType->isFunctionType()) {
155    assert(0 && "HandleVector(): Complex type construction unimplemented");
156    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
157     do {
158     if (PointerType *PT = dyn_cast<PointerType>(canonType))
159     canonType = PT->getPointeeType().getTypePtr();
160     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
161     canonType = AT->getElementType().getTypePtr();
162     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
163     canonType = FT->getResultType().getTypePtr();
164     } while (canonType->isPointerType() || canonType->isArrayType() ||
165     canonType->isFunctionType());
166     */
167  }
168  // the base type must be integer or float.
169  if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
170    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
171           CurType.getAsString());
172    return;
173  }
174  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
175  // vecSize is specified in bytes - convert to bits.
176  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
177
178  // the vector size needs to be an integral multiple of the type size.
179  if (vectorSize % typeSize) {
180    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size,
181           sizeExpr->getSourceRange());
182    return;
183  }
184  if (vectorSize == 0) {
185    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size,
186           sizeExpr->getSourceRange());
187    return;
188  }
189
190  // Success! Instantiate the vector type, the number of elements is > 0, and
191  // not required to be a power of 2, unlike GCC.
192  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
193
194  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
195    VD->setType(CurType);
196  else
197    cast<TypedefDecl>(D)->setUnderlyingType(CurType);
198}
199
200static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
201  // check the attribute arguments.
202  if (Attr.getNumArgs() > 0) {
203    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
204           std::string("0"));
205    return;
206  }
207
208  if (TagDecl *TD = dyn_cast<TagDecl>(d))
209    TD->addAttr(new PackedAttr());
210  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
211    // If the alignment is less than or equal to 8 bits, the packed attribute
212    // has no effect.
213    if (!FD->getType()->isIncompleteType() &&
214        S.Context.getTypeAlign(FD->getType()) <= 8)
215      S.Diag(Attr.getLoc(),
216             diag::warn_attribute_ignored_for_field_of_type,
217             Attr.getName()->getName(), FD->getType().getAsString());
218    else
219      FD->addAttr(new PackedAttr());
220  } else
221    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored,
222           Attr.getName()->getName());
223}
224
225static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
226  // check the attribute arguments.
227  if (Attr.getNumArgs() > 0) {
228    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
229           std::string("0"));
230    return;
231  }
232
233  // The IBOutlet attribute only applies to instance variables of Objective-C
234  // classes.
235  if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d))
236    ID->addAttr(new IBOutletAttr());
237  else
238    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar);
239}
240
241static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
242
243  // GCC ignores the nonnull attribute on K&R style function
244  // prototypes, so we ignore it as well
245  const FunctionTypeProto *proto = getFunctionProto(d);
246  if (!proto) {
247    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
248           "nonnull", "function");
249    return;
250  }
251
252  unsigned NumArgs = proto->getNumArgs();
253
254  // The nonnull attribute only applies to pointers.
255  llvm::SmallVector<unsigned, 10> NonNullArgs;
256
257  for (AttributeList::arg_iterator I=Attr.arg_begin(),
258                                   E=Attr.arg_end(); I!=E; ++I) {
259
260
261    // The argument must be an integer constant expression.
262    Expr *Ex = static_cast<Expr *>(Attr.getArg(0));
263    llvm::APSInt ArgNum(32);
264    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
265      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
266             "nonnull", Ex->getSourceRange());
267      return;
268    }
269
270    unsigned x = (unsigned) ArgNum.getZExtValue();
271
272    if (x < 1 || x > NumArgs) {
273      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
274             "nonnull", llvm::utostr_32(I.getArgNum()), Ex->getSourceRange());
275      return;
276    }
277
278    --x;
279
280    // Is the function argument a pointer type?
281    if (!proto->getArgType(x)->isPointerType()) {
282      // FIXME: Should also highlight argument in decl.
283      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only,
284             "nonnull", Ex->getSourceRange());
285      return;
286    }
287
288    NonNullArgs.push_back(x);
289  }
290
291  if (!NonNullArgs.empty()) {
292    unsigned* start = &NonNullArgs[0];
293    unsigned size = NonNullArgs.size();
294    std::sort(start, start + size);
295    d->addAttr(new NonNullAttr(start, size));
296  }
297  else
298    d->addAttr(new NonNullAttr());
299}
300
301static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
302  // check the attribute arguments.
303  if (Attr.getNumArgs() != 1) {
304    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
305           std::string("1"));
306    return;
307  }
308
309  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
310  Arg = Arg->IgnoreParenCasts();
311  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
312
313  if (Str == 0 || Str->isWide()) {
314    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
315           "alias", std::string("1"));
316    return;
317  }
318
319  const char *Alias = Str->getStrData();
320  unsigned AliasLen = Str->getByteLength();
321
322  // FIXME: check if target symbol exists in current file
323
324  d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
325}
326
327static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
328  // check the attribute arguments.
329  if (Attr.getNumArgs() != 0) {
330    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
331           std::string("0"));
332    return;
333  }
334
335  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
336  if (!Fn) {
337    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
338           "noreturn", "function");
339    return;
340  }
341
342  d->addAttr(new NoReturnAttr());
343}
344
345static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
346  // check the attribute arguments.
347  if (Attr.getNumArgs() != 0) {
348    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
349           std::string("0"));
350    return;
351  }
352
353  if (!isa<VarDecl>(d) && !getFunctionProto(d)) {
354    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
355           "unused", "variable and function");
356    return;
357  }
358
359  d->addAttr(new UnusedAttr());
360}
361
362static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
363  // check the attribute arguments.
364  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
365    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
366    return;
367  }
368
369  int priority = 65535; // FIXME: Do not hardcode such constants.
370  if (Attr.getNumArgs() > 0) {
371    Expr *E = static_cast<Expr *>(Attr.getArg(0));
372    llvm::APSInt Idx(32);
373    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
374      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
375             "constructor", "1", E->getSourceRange());
376      return;
377    }
378    priority = Idx.getZExtValue();
379  }
380
381  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
382  if (!Fn) {
383    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
384           "constructor", "function");
385    return;
386  }
387
388  d->addAttr(new ConstructorAttr(priority));
389}
390
391static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
392  // check the attribute arguments.
393  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
394    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1");
395    return;
396  }
397
398  int priority = 65535; // FIXME: Do not hardcode such constants.
399  if (Attr.getNumArgs() > 0) {
400    Expr *E = static_cast<Expr *>(Attr.getArg(0));
401    llvm::APSInt Idx(32);
402    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
403      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
404             "destructor", "1", E->getSourceRange());
405      return;
406    }
407    priority = Idx.getZExtValue();
408  }
409
410  if (!isa<FunctionDecl>(d)) {
411    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
412           "destructor", "function");
413    return;
414  }
415
416  d->addAttr(new DestructorAttr(priority));
417}
418
419static void HandleDeprecatedAttr(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,
423           std::string("0"));
424    return;
425  }
426
427  d->addAttr(new DeprecatedAttr());
428}
429
430static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
431  // check the attribute arguments.
432  if (Attr.getNumArgs() != 1) {
433    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
434           std::string("1"));
435    return;
436  }
437
438  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
439  Arg = Arg->IgnoreParenCasts();
440  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
441
442  if (Str == 0 || Str->isWide()) {
443    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
444           "visibility", std::string("1"));
445    return;
446  }
447
448  const char *TypeStr = Str->getStrData();
449  unsigned TypeLen = Str->getByteLength();
450  VisibilityAttr::VisibilityTypes type;
451
452  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
453    type = VisibilityAttr::DefaultVisibility;
454  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
455    type = VisibilityAttr::HiddenVisibility;
456  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
457    type = VisibilityAttr::HiddenVisibility; // FIXME
458  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
459    type = VisibilityAttr::ProtectedVisibility;
460  else {
461    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
462           "visibility", TypeStr);
463    return;
464  }
465
466  d->addAttr(new VisibilityAttr(type));
467}
468
469static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
470  // check the attribute arguments.
471  if (Attr.getNumArgs() != 0) {
472    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
473           std::string("0"));
474    return;
475  }
476
477  d->addAttr(new WeakAttr());
478}
479
480static void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
481  // check the attribute arguments.
482  if (Attr.getNumArgs() != 0) {
483    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
484           std::string("0"));
485    return;
486  }
487
488  d->addAttr(new DLLImportAttr());
489}
490
491static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
492  // check the attribute arguments.
493  if (Attr.getNumArgs() != 0) {
494    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
495           std::string("0"));
496    return;
497  }
498
499  d->addAttr(new DLLExportAttr());
500}
501
502static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
503  // check the attribute arguments.
504  if (Attr.getNumArgs() != 0) {
505    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
506           std::string("0"));
507    return;
508  }
509
510  d->addAttr(new StdCallAttr());
511}
512
513static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
514  // check the attribute arguments.
515  if (Attr.getNumArgs() != 0) {
516    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
517           std::string("0"));
518    return;
519  }
520
521  d->addAttr(new FastCallAttr());
522}
523
524static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
525  // check the attribute arguments.
526  if (Attr.getNumArgs() != 0) {
527    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
528           std::string("0"));
529    return;
530  }
531
532  d->addAttr(new NoThrowAttr());
533}
534
535/// Handle __attribute__((format(type,idx,firstarg))) attributes
536/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
537static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
538
539  if (!Attr.getParameterName()) {
540    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
541           "format", std::string("1"));
542    return;
543  }
544
545  if (Attr.getNumArgs() != 2) {
546    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
547           std::string("3"));
548    return;
549  }
550
551  // GCC ignores the format attribute on K&R style function
552  // prototypes, so we ignore it as well
553  const FunctionTypeProto *proto = getFunctionProto(d);
554
555  if (!proto) {
556    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
557           "format", "function");
558    return;
559  }
560
561  // FIXME: in C++ the implicit 'this' function parameter also counts.
562  // this is needed in order to be compatible with GCC
563  // the index must start in 1 and the limit is numargs+1
564  unsigned NumArgs  = proto->getNumArgs();
565  unsigned FirstIdx = 1;
566
567  const char *Format = Attr.getParameterName()->getName();
568  unsigned FormatLen = Attr.getParameterName()->getLength();
569
570  // Normalize the argument, __foo__ becomes foo.
571  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
572      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
573    Format += 2;
574    FormatLen -= 4;
575  }
576
577  bool Supported = false;
578  bool is_NSString = false;
579  bool is_strftime = false;
580
581  switch (FormatLen) {
582  default: break;
583  case 5: Supported = !memcmp(Format, "scanf", 5); break;
584  case 6: Supported = !memcmp(Format, "printf", 6); break;
585  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
586  case 8:
587    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
588                (is_NSString = !memcmp(Format, "NSString", 8));
589    break;
590  }
591
592  if (!Supported) {
593    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
594           "format", Attr.getParameterName()->getName());
595    return;
596  }
597
598  // checks for the 2nd argument
599  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
600  llvm::APSInt Idx(32);
601  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
602    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
603           "format", std::string("2"), IdxExpr->getSourceRange());
604    return;
605  }
606
607  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
608    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
609           "format", std::string("2"), IdxExpr->getSourceRange());
610    return;
611  }
612
613  // FIXME: Do we need to bounds check?
614  unsigned ArgIdx = Idx.getZExtValue() - 1;
615
616  // make sure the format string is really a string
617  QualType Ty = proto->getArgType(ArgIdx);
618
619  if (is_NSString) {
620    // FIXME: do we need to check if the type is NSString*?  What are
621    //  the semantics?
622    if (!isNSStringType(Ty, S.Context)) {
623      // FIXME: Should highlight the actual expression that has the
624      // wrong type.
625      S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString,
626             IdxExpr->getSourceRange());
627      return;
628    }
629  } else if (!Ty->isPointerType() ||
630             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
631    // FIXME: Should highlight the actual expression that has the
632    // wrong type.
633    S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string,
634           IdxExpr->getSourceRange());
635    return;
636  }
637
638  // check the 3rd argument
639  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
640  llvm::APSInt FirstArg(32);
641  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
642    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
643           "format", std::string("3"), FirstArgExpr->getSourceRange());
644    return;
645  }
646
647  // check if the function is variadic if the 3rd argument non-zero
648  if (FirstArg != 0) {
649    if (proto->isVariadic()) {
650      ++NumArgs; // +1 for ...
651    } else {
652      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
653      return;
654    }
655  }
656
657  // strftime requires FirstArg to be 0 because it doesn't read from any variable
658  // the input is just the current time + the format string
659  if (is_strftime) {
660    if (FirstArg != 0) {
661      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter,
662             FirstArgExpr->getSourceRange());
663      return;
664    }
665  // if 0 it disables parameter checking (to use with e.g. va_list)
666  } else if (FirstArg != 0 && FirstArg != NumArgs) {
667    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
668           "format", std::string("3"), FirstArgExpr->getSourceRange());
669    return;
670  }
671
672  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
673                            Idx.getZExtValue(), FirstArg.getZExtValue()));
674}
675
676static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
677                                       Sema &S) {
678  // check the attribute arguments.
679  if (Attr.getNumArgs() != 0) {
680    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
681         std::string("0"));
682    return;
683  }
684
685  TypeDecl *decl = dyn_cast<TypeDecl>(d);
686
687  if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) {
688    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
689         "transparent_union", "union");
690    return;
691  }
692
693  //QualType QTy = Context.getTypeDeclType(decl);
694  //const RecordType *Ty = QTy->getAsUnionType();
695
696// FIXME
697// Ty->addAttr(new TransparentUnionAttr());
698}
699
700static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
701  // check the attribute arguments.
702  if (Attr.getNumArgs() != 1) {
703    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
704           std::string("1"));
705    return;
706  }
707  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
708  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
709
710  // Make sure that there is a string literal as the annotation's single
711  // argument.
712  if (!SE) {
713    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
714    return;
715  }
716  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
717                                          SE->getByteLength())));
718}
719
720static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
721  // check the attribute arguments.
722  if (Attr.getNumArgs() > 1) {
723    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
724           std::string("1"));
725    return;
726  }
727
728  unsigned Align = 0;
729  if (Attr.getNumArgs() == 0) {
730    // FIXME: This should be the target specific maximum alignment.
731    // (For now we just use 128 bits which is the maximum on X86.
732    Align = 128;
733    return;
734  }
735
736  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
737  llvm::APSInt Alignment(32);
738  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
739    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
740           "aligned", alignmentExpr->getSourceRange());
741    return;
742  }
743  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
744}
745
746/// HandleModeAttr - This attribute modifies the width of a decl with
747/// primitive type.
748///
749/// Despite what would be logical, the mode attribute is a decl attribute,
750/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
751/// 'G' be HImode, not an intermediate pointer.
752///
753static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
754  // This attribute isn't documented, but glibc uses it.  It changes
755  // the width of an int or unsigned int to the specified size.
756
757  // Check that there aren't any arguments
758  if (Attr.getNumArgs() != 0) {
759    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
760           std::string("0"));
761    return;
762  }
763
764  IdentifierInfo *Name = Attr.getParameterName();
765  if (!Name) {
766    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
767    return;
768  }
769  const char *Str = Name->getName();
770  unsigned Len = Name->getLength();
771
772  // Normalize the attribute name, __foo__ becomes foo.
773  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
774      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
775    Str += 2;
776    Len -= 4;
777  }
778
779  unsigned DestWidth = 0;
780  bool IntegerMode = true;
781  switch (Len) {
782  case 2:
783    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
784    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
785    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
786    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
787    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
788    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
789    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
790    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
791    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
792    break;
793  case 4:
794    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
795    // pointer on PIC16 and other embedded platforms.
796    if (!memcmp(Str, "word", 4))
797      DestWidth = S.Context.Target.getPointerWidth(0);
798    if (!memcmp(Str, "byte", 4))
799      DestWidth = S.Context.Target.getCharWidth();
800    break;
801  case 7:
802    if (!memcmp(Str, "pointer", 7))
803      DestWidth = S.Context.Target.getPointerWidth(0);
804    break;
805  }
806
807  QualType OldTy;
808  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
809    OldTy = TD->getUnderlyingType();
810  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
811    OldTy = VD->getType();
812  else {
813    S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode",
814           SourceRange(Attr.getLoc(), Attr.getLoc()));
815    return;
816  }
817
818  // FIXME: Need proper fixed-width types
819  QualType NewTy;
820  switch (DestWidth) {
821  case 0:
822    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName());
823    return;
824  default:
825    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName());
826    return;
827  case 8:
828    assert(IntegerMode);
829    if (OldTy->isSignedIntegerType())
830      NewTy = S.Context.SignedCharTy;
831    else
832      NewTy = S.Context.UnsignedCharTy;
833    break;
834  case 16:
835    assert(IntegerMode);
836    if (OldTy->isSignedIntegerType())
837      NewTy = S.Context.ShortTy;
838    else
839      NewTy = S.Context.UnsignedShortTy;
840    break;
841  case 32:
842    if (!IntegerMode)
843      NewTy = S.Context.FloatTy;
844    else if (OldTy->isSignedIntegerType())
845      NewTy = S.Context.IntTy;
846    else
847      NewTy = S.Context.UnsignedIntTy;
848    break;
849  case 64:
850    if (!IntegerMode)
851      NewTy = S.Context.DoubleTy;
852    else if (OldTy->isSignedIntegerType())
853      NewTy = S.Context.LongLongTy;
854    else
855      NewTy = S.Context.UnsignedLongLongTy;
856    break;
857  }
858
859  if (!OldTy->getAsBuiltinType())
860    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
861  else if (!(IntegerMode && OldTy->isIntegerType()) &&
862           !(!IntegerMode && OldTy->isFloatingType())) {
863    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
864  }
865
866  // Install the new type.
867  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
868    TD->setUnderlyingType(NewTy);
869  else
870    cast<ValueDecl>(D)->setType(NewTy);
871}
872
873//===----------------------------------------------------------------------===//
874// Top Level Sema Entry Points
875//===----------------------------------------------------------------------===//
876
877/// HandleDeclAttribute - Apply the specific attribute to the specified decl if
878/// the attribute applies to decls.  If the attribute is a type attribute, just
879/// silently ignore it.
880static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
881  switch (Attr.getKind()) {
882  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
883  case AttributeList::AT_address_space:
884    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
885    break;
886  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
887  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
888  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
889  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
890  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
891  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
892  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
893  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
894  case AttributeList::AT_ext_vector_type:
895    HandleExtVectorTypeAttr(D, Attr, S);
896    break;
897  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
898  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
899  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
900  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
901  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
902  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
903  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
904  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
905  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
906  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
907  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
908  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
909  case AttributeList::AT_transparent_union:
910    HandleTransparentUnionAttr(D, Attr, S);
911    break;
912  default:
913#if 0
914    // TODO: when we have the full set of attributes, warn about unknown ones.
915    S.Diag(Attr->getLoc(), diag::warn_attribute_ignored,
916           Attr->getName()->getName());
917#endif
918    break;
919  }
920}
921
922/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
923/// attribute list to the specified decl, ignoring any type attributes.
924void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
925  while (AttrList) {
926    ProcessDeclAttribute(D, *AttrList, *this);
927    AttrList = AttrList->getNext();
928  }
929}
930
931
932/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
933/// it, apply them to D.  This is a bit tricky because PD can have attributes
934/// specified in many different places, and we need to find and apply them all.
935void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
936  // Apply decl attributes from the DeclSpec if present.
937  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
938    ProcessDeclAttributeList(D, Attrs);
939
940  // Walk the declarator structure, applying decl attributes that were in a type
941  // position to the decl itself.  This handles cases like:
942  //   int *__attr__(x)** D;
943  // when X is a decl attribute.
944  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
945    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
946      ProcessDeclAttributeList(D, Attrs);
947
948  // Finally, apply any attributes on the decl itself.
949  if (const AttributeList *Attrs = PD.getAttributes())
950    ProcessDeclAttributeList(D, Attrs);
951}
952
953