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