SemaDeclAttr.cpp revision acc5f3e42334525bf28c86471551f83dfce222d5
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  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
411  if (!Fn) {
412    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
413           "destructor", "function");
414    return;
415  }
416
417  d->addAttr(new DestructorAttr(priority));
418}
419
420static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
421  // check the attribute arguments.
422  if (Attr.getNumArgs() != 0) {
423    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
424           std::string("0"));
425    return;
426  }
427
428  d->addAttr(new DeprecatedAttr());
429}
430
431static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
432  // check the attribute arguments.
433  if (Attr.getNumArgs() != 1) {
434    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
435           std::string("1"));
436    return;
437  }
438
439  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
440  Arg = Arg->IgnoreParenCasts();
441  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
442
443  if (Str == 0 || Str->isWide()) {
444    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
445           "visibility", std::string("1"));
446    return;
447  }
448
449  const char *TypeStr = Str->getStrData();
450  unsigned TypeLen = Str->getByteLength();
451  VisibilityAttr::VisibilityTypes type;
452
453  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
454    type = VisibilityAttr::DefaultVisibility;
455  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
456    type = VisibilityAttr::HiddenVisibility;
457  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
458    type = VisibilityAttr::HiddenVisibility; // FIXME
459  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
460    type = VisibilityAttr::ProtectedVisibility;
461  else {
462    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
463           "visibility", TypeStr);
464    return;
465  }
466
467  d->addAttr(new VisibilityAttr(type));
468}
469
470static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
471  // check the attribute arguments.
472  if (Attr.getNumArgs() != 0) {
473    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
474           std::string("0"));
475    return;
476  }
477
478  d->addAttr(new WeakAttr());
479}
480
481static void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
482  // check the attribute arguments.
483  if (Attr.getNumArgs() != 0) {
484    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
485           std::string("0"));
486    return;
487  }
488
489  d->addAttr(new DLLImportAttr());
490}
491
492static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
493  // check the attribute arguments.
494  if (Attr.getNumArgs() != 0) {
495    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
496           std::string("0"));
497    return;
498  }
499
500  d->addAttr(new DLLExportAttr());
501}
502
503static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
504  // check the attribute arguments.
505  if (Attr.getNumArgs() != 0) {
506    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
507           std::string("0"));
508    return;
509  }
510
511  d->addAttr(new StdCallAttr());
512}
513
514static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
515  // check the attribute arguments.
516  if (Attr.getNumArgs() != 0) {
517    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
518           std::string("0"));
519    return;
520  }
521
522  d->addAttr(new FastCallAttr());
523}
524
525static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
526  // check the attribute arguments.
527  if (Attr.getNumArgs() != 0) {
528    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
529           std::string("0"));
530    return;
531  }
532
533  d->addAttr(new NoThrowAttr());
534}
535
536/// Handle __attribute__((format(type,idx,firstarg))) attributes
537/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
538static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
539
540  if (!Attr.getParameterName()) {
541    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
542           "format", std::string("1"));
543    return;
544  }
545
546  if (Attr.getNumArgs() != 2) {
547    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
548           std::string("3"));
549    return;
550  }
551
552  // GCC ignores the format attribute on K&R style function
553  // prototypes, so we ignore it as well
554  const FunctionTypeProto *proto = getFunctionProto(d);
555
556  if (!proto) {
557    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
558           "format", "function");
559    return;
560  }
561
562  // FIXME: in C++ the implicit 'this' function parameter also counts.
563  // this is needed in order to be compatible with GCC
564  // the index must start in 1 and the limit is numargs+1
565  unsigned NumArgs  = proto->getNumArgs();
566  unsigned FirstIdx = 1;
567
568  const char *Format = Attr.getParameterName()->getName();
569  unsigned FormatLen = Attr.getParameterName()->getLength();
570
571  // Normalize the argument, __foo__ becomes foo.
572  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
573      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
574    Format += 2;
575    FormatLen -= 4;
576  }
577
578  bool Supported = false;
579  bool is_NSString = false;
580  bool is_strftime = false;
581
582  switch (FormatLen) {
583  default: break;
584  case 5: Supported = !memcmp(Format, "scanf", 5); break;
585  case 6: Supported = !memcmp(Format, "printf", 6); break;
586  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
587  case 8:
588    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
589                (is_NSString = !memcmp(Format, "NSString", 8));
590    break;
591  }
592
593  if (!Supported) {
594    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
595           "format", Attr.getParameterName()->getName());
596    return;
597  }
598
599  // checks for the 2nd argument
600  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
601  llvm::APSInt Idx(32);
602  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
603    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
604           "format", std::string("2"), IdxExpr->getSourceRange());
605    return;
606  }
607
608  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
609    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
610           "format", std::string("2"), IdxExpr->getSourceRange());
611    return;
612  }
613
614  // FIXME: Do we need to bounds check?
615  unsigned ArgIdx = Idx.getZExtValue() - 1;
616
617  // make sure the format string is really a string
618  QualType Ty = proto->getArgType(ArgIdx);
619
620  if (is_NSString) {
621    // FIXME: do we need to check if the type is NSString*?  What are
622    //  the semantics?
623    if (!isNSStringType(Ty, S.Context)) {
624      // FIXME: Should highlight the actual expression that has the
625      // wrong type.
626      S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString,
627             IdxExpr->getSourceRange());
628      return;
629    }
630  } else if (!Ty->isPointerType() ||
631             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
632    // FIXME: Should highlight the actual expression that has the
633    // wrong type.
634    S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string,
635           IdxExpr->getSourceRange());
636    return;
637  }
638
639  // check the 3rd argument
640  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
641  llvm::APSInt FirstArg(32);
642  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
643    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
644           "format", std::string("3"), FirstArgExpr->getSourceRange());
645    return;
646  }
647
648  // check if the function is variadic if the 3rd argument non-zero
649  if (FirstArg != 0) {
650    if (proto->isVariadic()) {
651      ++NumArgs; // +1 for ...
652    } else {
653      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
654      return;
655    }
656  }
657
658  // strftime requires FirstArg to be 0 because it doesn't read from any variable
659  // the input is just the current time + the format string
660  if (is_strftime) {
661    if (FirstArg != 0) {
662      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter,
663             FirstArgExpr->getSourceRange());
664      return;
665    }
666  // if 0 it disables parameter checking (to use with e.g. va_list)
667  } else if (FirstArg != 0 && FirstArg != NumArgs) {
668    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
669           "format", std::string("3"), FirstArgExpr->getSourceRange());
670    return;
671  }
672
673  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
674                            Idx.getZExtValue(), FirstArg.getZExtValue()));
675}
676
677static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
678                                       Sema &S) {
679  // check the attribute arguments.
680  if (Attr.getNumArgs() != 0) {
681    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
682         std::string("0"));
683    return;
684  }
685
686  TypeDecl *decl = dyn_cast<TypeDecl>(d);
687
688  if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) {
689    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
690         "transparent_union", "union");
691    return;
692  }
693
694  //QualType QTy = Context.getTypeDeclType(decl);
695  //const RecordType *Ty = QTy->getAsUnionType();
696
697// FIXME
698// Ty->addAttr(new TransparentUnionAttr());
699}
700
701static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
702  // check the attribute arguments.
703  if (Attr.getNumArgs() != 1) {
704    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
705           std::string("1"));
706    return;
707  }
708  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
709  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
710
711  // Make sure that there is a string literal as the annotation's single
712  // argument.
713  if (!SE) {
714    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
715    return;
716  }
717  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
718                                          SE->getByteLength())));
719}
720
721static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
722  // check the attribute arguments.
723  if (Attr.getNumArgs() > 1) {
724    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
725           std::string("1"));
726    return;
727  }
728
729  unsigned Align = 0;
730  if (Attr.getNumArgs() == 0) {
731    // FIXME: This should be the target specific maximum alignment.
732    // (For now we just use 128 bits which is the maximum on X86.
733    Align = 128;
734    return;
735  }
736
737  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
738  llvm::APSInt Alignment(32);
739  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
740    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
741           "aligned", alignmentExpr->getSourceRange());
742    return;
743  }
744  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
745}
746
747/// HandleModeAttr - This attribute modifies the width of a decl with
748/// primitive type.
749///
750/// Despite what would be logical, the mode attribute is a decl attribute,
751/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
752/// 'G' be HImode, not an intermediate pointer.
753///
754static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
755  // This attribute isn't documented, but glibc uses it.  It changes
756  // the width of an int or unsigned int to the specified size.
757
758  // Check that there aren't any arguments
759  if (Attr.getNumArgs() != 0) {
760    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
761           std::string("0"));
762    return;
763  }
764
765  IdentifierInfo *Name = Attr.getParameterName();
766  if (!Name) {
767    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
768    return;
769  }
770  const char *Str = Name->getName();
771  unsigned Len = Name->getLength();
772
773  // Normalize the attribute name, __foo__ becomes foo.
774  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
775      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
776    Str += 2;
777    Len -= 4;
778  }
779
780  unsigned DestWidth = 0;
781  bool IntegerMode = true;
782  switch (Len) {
783  case 2:
784    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
785    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
786    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
787    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
788    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
789    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
790    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
791    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
792    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
793    break;
794  case 4:
795    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
796    // pointer on PIC16 and other embedded platforms.
797    if (!memcmp(Str, "word", 4))
798      DestWidth = S.Context.Target.getPointerWidth(0);
799    if (!memcmp(Str, "byte", 4))
800      DestWidth = S.Context.Target.getCharWidth();
801    break;
802  case 7:
803    if (!memcmp(Str, "pointer", 7))
804      DestWidth = S.Context.Target.getPointerWidth(0);
805    break;
806  }
807
808  QualType OldTy;
809  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
810    OldTy = TD->getUnderlyingType();
811  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
812    OldTy = VD->getType();
813  else {
814    S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode",
815           SourceRange(Attr.getLoc(), Attr.getLoc()));
816    return;
817  }
818
819  // FIXME: Need proper fixed-width types
820  QualType NewTy;
821  switch (DestWidth) {
822  case 0:
823    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName());
824    return;
825  default:
826    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName());
827    return;
828  case 8:
829    assert(IntegerMode);
830    if (OldTy->isSignedIntegerType())
831      NewTy = S.Context.SignedCharTy;
832    else
833      NewTy = S.Context.UnsignedCharTy;
834    break;
835  case 16:
836    assert(IntegerMode);
837    if (OldTy->isSignedIntegerType())
838      NewTy = S.Context.ShortTy;
839    else
840      NewTy = S.Context.UnsignedShortTy;
841    break;
842  case 32:
843    if (!IntegerMode)
844      NewTy = S.Context.FloatTy;
845    else if (OldTy->isSignedIntegerType())
846      NewTy = S.Context.IntTy;
847    else
848      NewTy = S.Context.UnsignedIntTy;
849    break;
850  case 64:
851    if (!IntegerMode)
852      NewTy = S.Context.DoubleTy;
853    else if (OldTy->isSignedIntegerType())
854      NewTy = S.Context.LongLongTy;
855    else
856      NewTy = S.Context.UnsignedLongLongTy;
857    break;
858  }
859
860  if (!OldTy->getAsBuiltinType())
861    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
862  else if (!(IntegerMode && OldTy->isIntegerType()) &&
863           !(!IntegerMode && OldTy->isFloatingType())) {
864    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
865  }
866
867  // Install the new type.
868  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
869    TD->setUnderlyingType(NewTy);
870  else
871    cast<ValueDecl>(D)->setType(NewTy);
872}
873
874//===----------------------------------------------------------------------===//
875// Top Level Sema Entry Points
876//===----------------------------------------------------------------------===//
877
878/// HandleDeclAttribute - Apply the specific attribute to the specified decl if
879/// the attribute applies to decls.  If the attribute is a type attribute, just
880/// silently ignore it.
881static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
882  switch (Attr.getKind()) {
883  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
884  case AttributeList::AT_address_space:
885    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
886    break;
887  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
888  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
889  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
890  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
891  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
892  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
893  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
894  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
895  case AttributeList::AT_ext_vector_type:
896    HandleExtVectorTypeAttr(D, Attr, S);
897    break;
898  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
899  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
900  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
901  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
902  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
903  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
904  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
905  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
906  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
907  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
908  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
909  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
910  case AttributeList::AT_transparent_union:
911    HandleTransparentUnionAttr(D, Attr, S);
912    break;
913  default:
914#if 0
915    // TODO: when we have the full set of attributes, warn about unknown ones.
916    S.Diag(Attr->getLoc(), diag::warn_attribute_ignored,
917           Attr->getName()->getName());
918#endif
919    break;
920  }
921}
922
923/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
924/// attribute list to the specified decl, ignoring any type attributes.
925void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
926  while (AttrList) {
927    ProcessDeclAttribute(D, *AttrList, *this);
928    AttrList = AttrList->getNext();
929  }
930}
931
932
933/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
934/// it, apply them to D.  This is a bit tricky because PD can have attributes
935/// specified in many different places, and we need to find and apply them all.
936void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
937  // Apply decl attributes from the DeclSpec if present.
938  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
939    ProcessDeclAttributeList(D, Attrs);
940
941  // Walk the declarator structure, applying decl attributes that were in a type
942  // position to the decl itself.  This handles cases like:
943  //   int *__attr__(x)** D;
944  // when X is a decl attribute.
945  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
946    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
947      ProcessDeclAttributeList(D, Attrs);
948
949  // Finally, apply any attributes on the decl itself.
950  if (const AttributeList *Attrs = PD.getAttributes())
951    ProcessDeclAttributeList(D, Attrs);
952}
953
954