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