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