blob: 8d715f1cdcd8c7cf0b7f79c71be173dc62787408 [file] [log] [blame]
Chris Lattner6953a072008-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"
16
17using 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;
83 case AttributeList::AT_mode:
84 // Despite what would be logical, the mode attribute is a decl attribute,
85 // not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
86 // 'G' be HImode, not an intermediate pointer.
87 if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
88 QualType newType = HandleModeTypeAttribute(tDecl->getUnderlyingType(),
89 Attr);
90 tDecl->setUnderlyingType(newType);
91 } else if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) {
92 QualType newType = HandleModeTypeAttribute(vDecl->getType(), Attr);
93 vDecl->setType(newType);
94 }
95 // FIXME: Diagnostic?
96 break;
97 case AttributeList::AT_alias: HandleAliasAttribute(New, Attr); break;
98 case AttributeList::AT_deprecated: HandleDeprecatedAttribute(New, Attr);break;
99 case AttributeList::AT_visibility: HandleVisibilityAttribute(New, Attr);break;
100 case AttributeList::AT_weak: HandleWeakAttribute(New, Attr); break;
101 case AttributeList::AT_dllimport: HandleDLLImportAttribute(New, Attr); break;
102 case AttributeList::AT_dllexport: HandleDLLExportAttribute(New, Attr); break;
103 case AttributeList::AT_nothrow: HandleNothrowAttribute(New, Attr); break;
104 case AttributeList::AT_stdcall: HandleStdCallAttribute(New, Attr); break;
105 case AttributeList::AT_fastcall: HandleFastCallAttribute(New, Attr); break;
106 case AttributeList::AT_aligned: HandleAlignedAttribute(New, Attr); break;
107 case AttributeList::AT_packed: HandlePackedAttribute(New, Attr); break;
108 case AttributeList::AT_annotate: HandleAnnotateAttribute(New, Attr); break;
109 case AttributeList::AT_noreturn: HandleNoReturnAttribute(New, Attr); break;
110 case AttributeList::AT_format: HandleFormatAttribute(New, Attr); break;
111 case AttributeList::AT_transparent_union:
112 HandleTransparentUnionAttribute(New, Attr);
113 break;
114 default:
115#if 0
116 // TODO: when we have the full set of attributes, warn about unknown ones.
117 Diag(Attr->getLoc(), diag::warn_attribute_ignored,
118 Attr->getName()->getName());
119#endif
120 break;
121 }
122}
123
124void Sema::HandleDeclAttributes(Decl *New, const AttributeList *DeclSpecAttrs,
125 const AttributeList *DeclaratorAttrs) {
126 if (DeclSpecAttrs == 0 && DeclaratorAttrs == 0) return;
127
128 while (DeclSpecAttrs) {
129 HandleDeclAttribute(New, DeclSpecAttrs);
130 DeclSpecAttrs = DeclSpecAttrs->getNext();
131 }
132
133 // If there are any type attributes that were in the declarator, apply them to
134 // its top level type.
135 if (ValueDecl *VD = dyn_cast<ValueDecl>(New)) {
136 QualType DT = VD->getType();
137 ProcessTypeAttributes(DT, DeclaratorAttrs);
138 VD->setType(DT);
139 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(New)) {
140 QualType DT = TD->getUnderlyingType();
141 ProcessTypeAttributes(DT, DeclaratorAttrs);
142 TD->setUnderlyingType(DT);
143 }
144
145 while (DeclaratorAttrs) {
146 HandleDeclAttribute(New, DeclaratorAttrs);
147 DeclaratorAttrs = DeclaratorAttrs->getNext();
148 }
149}
150
151void Sema::HandleExtVectorTypeAttribute(TypedefDecl *tDecl,
152 const AttributeList *rawAttr) {
153 QualType curType = tDecl->getUnderlyingType();
154 // check the attribute arguments.
155 if (rawAttr->getNumArgs() != 1) {
156 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
157 std::string("1"));
158 return;
159 }
160 Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
161 llvm::APSInt vecSize(32);
162 if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
163 Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int,
164 "ext_vector_type", sizeExpr->getSourceRange());
165 return;
166 }
167 // unlike gcc's vector_size attribute, we do not allow vectors to be defined
168 // in conjunction with complex types (pointers, arrays, functions, etc.).
169 Type *canonType = curType.getCanonicalType().getTypePtr();
170 if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
171 Diag(rawAttr->getLoc(), diag::err_attribute_invalid_vector_type,
172 curType.getCanonicalType().getAsString());
173 return;
174 }
175 // unlike gcc's vector_size attribute, the size is specified as the
176 // number of elements, not the number of bytes.
177 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
178
179 if (vectorSize == 0) {
180 Diag(rawAttr->getLoc(), diag::err_attribute_zero_size,
181 sizeExpr->getSourceRange());
182 return;
183 }
184 // Instantiate/Install the vector type, the number of elements is > 0.
185 tDecl->setUnderlyingType(Context.getExtVectorType(curType, vectorSize));
186 // Remember this typedef decl, we will need it later for diagnostics.
187 ExtVectorDecls.push_back(tDecl);
188}
189
190QualType Sema::HandleVectorTypeAttribute(QualType curType,
191 const AttributeList *rawAttr) {
192 // check the attribute arugments.
193 if (rawAttr->getNumArgs() != 1) {
194 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
195 std::string("1"));
196 return QualType();
197 }
198 Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
199 llvm::APSInt vecSize(32);
200 if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
201 Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int,
202 "vector_size", sizeExpr->getSourceRange());
203 return QualType();
204 }
205 // navigate to the base type - we need to provide for vector pointers,
206 // vector arrays, and functions returning vectors.
207 Type *canonType = curType.getCanonicalType().getTypePtr();
208
209 if (canonType->isPointerType() || canonType->isArrayType() ||
210 canonType->isFunctionType()) {
211 assert(0 && "HandleVector(): Complex type construction unimplemented");
212 /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
213 do {
214 if (PointerType *PT = dyn_cast<PointerType>(canonType))
215 canonType = PT->getPointeeType().getTypePtr();
216 else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
217 canonType = AT->getElementType().getTypePtr();
218 else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
219 canonType = FT->getResultType().getTypePtr();
220 } while (canonType->isPointerType() || canonType->isArrayType() ||
221 canonType->isFunctionType());
222 */
223 }
224 // the base type must be integer or float.
225 if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
226 Diag(rawAttr->getLoc(), diag::err_attribute_invalid_vector_type,
227 curType.getCanonicalType().getAsString());
228 return QualType();
229 }
230 unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(curType));
231 // vecSize is specified in bytes - convert to bits.
232 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
233
234 // the vector size needs to be an integral multiple of the type size.
235 if (vectorSize % typeSize) {
236 Diag(rawAttr->getLoc(), diag::err_attribute_invalid_size,
237 sizeExpr->getSourceRange());
238 return QualType();
239 }
240 if (vectorSize == 0) {
241 Diag(rawAttr->getLoc(), diag::err_attribute_zero_size,
242 sizeExpr->getSourceRange());
243 return QualType();
244 }
245 // Instantiate the vector type, the number of elements is > 0, and not
246 // required to be a power of 2, unlike GCC.
247 return Context.getVectorType(curType, vectorSize/typeSize);
248}
249
250void Sema::HandlePackedAttribute(Decl *d, const AttributeList *rawAttr) {
251 // check the attribute arguments.
252 if (rawAttr->getNumArgs() > 0) {
253 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
254 std::string("0"));
255 return;
256 }
257
258 if (TagDecl *TD = dyn_cast<TagDecl>(d))
259 TD->addAttr(new PackedAttr);
260 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
261 // If the alignment is less than or equal to 8 bits, the packed attribute
262 // has no effect.
263 if (!FD->getType()->isIncompleteType() &&
264 Context.getTypeAlign(FD->getType()) <= 8)
265 Diag(rawAttr->getLoc(),
266 diag::warn_attribute_ignored_for_field_of_type,
267 rawAttr->getName()->getName(), FD->getType().getAsString());
268 else
269 FD->addAttr(new PackedAttr);
270 } else
271 Diag(rawAttr->getLoc(), diag::warn_attribute_ignored,
272 rawAttr->getName()->getName());
273}
274
275void Sema::HandleAliasAttribute(Decl *d, const AttributeList *rawAttr) {
276 // check the attribute arguments.
277 if (rawAttr->getNumArgs() != 1) {
278 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
279 std::string("1"));
280 return;
281 }
282
283 Expr *Arg = static_cast<Expr*>(rawAttr->getArg(0));
284 Arg = Arg->IgnoreParenCasts();
285 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
286
287 if (Str == 0 || Str->isWide()) {
288 Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
289 "alias", std::string("1"));
290 return;
291 }
292
293 const char *Alias = Str->getStrData();
294 unsigned AliasLen = Str->getByteLength();
295
296 // FIXME: check if target symbol exists in current file
297
298 d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
299}
300
301void Sema::HandleNoReturnAttribute(Decl *d, const AttributeList *rawAttr) {
302 // check the attribute arguments.
303 if (rawAttr->getNumArgs() != 0) {
304 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
305 std::string("0"));
306 return;
307 }
308
309 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
310
311 if (!Fn) {
312 Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type,
313 "noreturn", "function");
314 return;
315 }
316
317 d->addAttr(new NoReturnAttr());
318}
319
320void Sema::HandleDeprecatedAttribute(Decl *d, const AttributeList *rawAttr) {
321 // check the attribute arguments.
322 if (rawAttr->getNumArgs() != 0) {
323 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
324 std::string("0"));
325 return;
326 }
327
328 d->addAttr(new DeprecatedAttr());
329}
330
331void Sema::HandleVisibilityAttribute(Decl *d, const AttributeList *rawAttr) {
332 // check the attribute arguments.
333 if (rawAttr->getNumArgs() != 1) {
334 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
335 std::string("1"));
336 return;
337 }
338
339 Expr *Arg = static_cast<Expr*>(rawAttr->getArg(0));
340 Arg = Arg->IgnoreParenCasts();
341 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
342
343 if (Str == 0 || Str->isWide()) {
344 Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
345 "visibility", std::string("1"));
346 return;
347 }
348
349 const char *TypeStr = Str->getStrData();
350 unsigned TypeLen = Str->getByteLength();
351 VisibilityAttr::VisibilityTypes type;
352
353 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
354 type = VisibilityAttr::DefaultVisibility;
355 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
356 type = VisibilityAttr::HiddenVisibility;
357 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
358 type = VisibilityAttr::HiddenVisibility; // FIXME
359 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
360 type = VisibilityAttr::ProtectedVisibility;
361 else {
362 Diag(rawAttr->getLoc(), diag::warn_attribute_type_not_supported,
363 "visibility", TypeStr);
364 return;
365 }
366
367 d->addAttr(new VisibilityAttr(type));
368}
369
370void Sema::HandleWeakAttribute(Decl *d, const AttributeList *rawAttr) {
371 // check the attribute arguments.
372 if (rawAttr->getNumArgs() != 0) {
373 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
374 std::string("0"));
375 return;
376 }
377
378 d->addAttr(new WeakAttr());
379}
380
381void Sema::HandleDLLImportAttribute(Decl *d, const AttributeList *rawAttr) {
382 // check the attribute arguments.
383 if (rawAttr->getNumArgs() != 0) {
384 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
385 std::string("0"));
386 return;
387 }
388
389 d->addAttr(new DLLImportAttr());
390}
391
392void Sema::HandleDLLExportAttribute(Decl *d, const AttributeList *rawAttr) {
393 // check the attribute arguments.
394 if (rawAttr->getNumArgs() != 0) {
395 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
396 std::string("0"));
397 return;
398 }
399
400 d->addAttr(new DLLExportAttr());
401}
402
403void Sema::HandleStdCallAttribute(Decl *d, const AttributeList *rawAttr) {
404 // check the attribute arguments.
405 if (rawAttr->getNumArgs() != 0) {
406 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
407 std::string("0"));
408 return;
409 }
410
411 d->addAttr(new StdCallAttr());
412}
413
414void Sema::HandleFastCallAttribute(Decl *d, const AttributeList *rawAttr) {
415 // check the attribute arguments.
416 if (rawAttr->getNumArgs() != 0) {
417 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
418 std::string("0"));
419 return;
420 }
421
422 d->addAttr(new FastCallAttr());
423}
424
425void Sema::HandleNothrowAttribute(Decl *d, const AttributeList *rawAttr) {
426 // check the attribute arguments.
427 if (rawAttr->getNumArgs() != 0) {
428 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
429 std::string("0"));
430 return;
431 }
432
433 d->addAttr(new NoThrowAttr());
434}
435
436/// Handle __attribute__((format(type,idx,firstarg))) attributes
437/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
438void Sema::HandleFormatAttribute(Decl *d, const AttributeList *rawAttr) {
439
440 if (!rawAttr->getParameterName()) {
441 Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string,
442 "format", std::string("1"));
443 return;
444 }
445
446 if (rawAttr->getNumArgs() != 2) {
447 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
448 std::string("3"));
449 return;
450 }
451
452 // GCC ignores the format attribute on K&R style function
453 // prototypes, so we ignore it as well
454 const FunctionTypeProto *proto = getFunctionProto(d);
455
456 if (!proto) {
457 Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type,
458 "format", "function");
459 return;
460 }
461
462 // FIXME: in C++ the implicit 'this' function parameter also counts.
463 // this is needed in order to be compatible with GCC
464 // the index must start in 1 and the limit is numargs+1
465 unsigned NumArgs = proto->getNumArgs();
466 unsigned FirstIdx = 1;
467
468 const char *Format = rawAttr->getParameterName()->getName();
469 unsigned FormatLen = rawAttr->getParameterName()->getLength();
470
471 // Normalize the argument, __foo__ becomes foo.
472 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
473 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
474 Format += 2;
475 FormatLen -= 4;
476 }
477
478 bool Supported = false;
479 bool is_NSString = false;
480 bool is_strftime = false;
481
482 switch (FormatLen) {
483 default: break;
484 case 5:
485 Supported = !memcmp(Format, "scanf", 5);
486 break;
487 case 6:
488 Supported = !memcmp(Format, "printf", 6);
489 break;
490 case 7:
491 Supported = !memcmp(Format, "strfmon", 7);
492 break;
493 case 8:
494 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
495 (is_NSString = !memcmp(Format, "NSString", 8));
496 break;
497 }
498
499 if (!Supported) {
500 Diag(rawAttr->getLoc(), diag::warn_attribute_type_not_supported,
501 "format", rawAttr->getParameterName()->getName());
502 return;
503 }
504
505 // checks for the 2nd argument
506 Expr *IdxExpr = static_cast<Expr *>(rawAttr->getArg(0));
507 llvm::APSInt Idx(Context.getTypeSize(IdxExpr->getType()));
508 if (!IdxExpr->isIntegerConstantExpr(Idx, Context)) {
509 Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int,
510 "format", std::string("2"), IdxExpr->getSourceRange());
511 return;
512 }
513
514 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
515 Diag(rawAttr->getLoc(), diag::err_attribute_argument_out_of_bounds,
516 "format", std::string("2"), IdxExpr->getSourceRange());
517 return;
518 }
519
520 // FIXME: Do we need to bounds check?
521 unsigned ArgIdx = Idx.getZExtValue() - 1;
522
523 // make sure the format string is really a string
524 QualType Ty = proto->getArgType(ArgIdx);
525
526 if (is_NSString) {
527 // FIXME: do we need to check if the type is NSString*? What are
528 // the semantics?
529 if (!isNSStringType(Ty, Context)) {
530 // FIXME: Should highlight the actual expression that has the
531 // wrong type.
532 Diag(rawAttr->getLoc(), diag::err_format_attribute_not_NSString,
533 IdxExpr->getSourceRange());
534 return;
535 }
536 } else if (!Ty->isPointerType() ||
537 !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
538 // FIXME: Should highlight the actual expression that has the
539 // wrong type.
540 Diag(rawAttr->getLoc(), diag::err_format_attribute_not_string,
541 IdxExpr->getSourceRange());
542 return;
543 }
544
545 // check the 3rd argument
546 Expr *FirstArgExpr = static_cast<Expr *>(rawAttr->getArg(1));
547 llvm::APSInt FirstArg(Context.getTypeSize(FirstArgExpr->getType()));
548 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, Context)) {
549 Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int,
550 "format", std::string("3"), FirstArgExpr->getSourceRange());
551 return;
552 }
553
554 // check if the function is variadic if the 3rd argument non-zero
555 if (FirstArg != 0) {
556 if (proto->isVariadic()) {
557 ++NumArgs; // +1 for ...
558 } else {
559 Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
560 return;
561 }
562 }
563
564 // strftime requires FirstArg to be 0 because it doesn't read from any variable
565 // the input is just the current time + the format string
566 if (is_strftime) {
567 if (FirstArg != 0) {
568 Diag(rawAttr->getLoc(), diag::err_format_strftime_third_parameter,
569 FirstArgExpr->getSourceRange());
570 return;
571 }
572 // if 0 it disables parameter checking (to use with e.g. va_list)
573 } else if (FirstArg != 0 && FirstArg != NumArgs) {
574 Diag(rawAttr->getLoc(), diag::err_attribute_argument_out_of_bounds,
575 "format", std::string("3"), FirstArgExpr->getSourceRange());
576 return;
577 }
578
579 d->addAttr(new FormatAttr(std::string(Format, FormatLen),
580 Idx.getZExtValue(), FirstArg.getZExtValue()));
581}
582
583void Sema::HandleTransparentUnionAttribute(Decl *d,
584 const AttributeList *rawAttr) {
585 // check the attribute arguments.
586 if (rawAttr->getNumArgs() != 0) {
587 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
588 std::string("0"));
589 return;
590 }
591
592 TypeDecl *decl = dyn_cast<TypeDecl>(d);
593
594 if (!decl || !Context.getTypeDeclType(decl)->isUnionType()) {
595 Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type,
596 "transparent_union", "union");
597 return;
598 }
599
600 //QualType QTy = Context.getTypeDeclType(decl);
601 //const RecordType *Ty = QTy->getAsUnionType();
602
603// FIXME
604// Ty->addAttr(new TransparentUnionAttr());
605}
606
607void Sema::HandleAnnotateAttribute(Decl *d, const AttributeList *rawAttr) {
608 // check the attribute arguments.
609 if (rawAttr->getNumArgs() != 1) {
610 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
611 std::string("1"));
612 return;
613 }
614 Expr *argExpr = static_cast<Expr *>(rawAttr->getArg(0));
615 StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
616
617 // Make sure that there is a string literal as the annotation's single
618 // argument.
619 if (!SE) {
620 Diag(rawAttr->getLoc(), diag::err_attribute_annotate_no_string);
621 return;
622 }
623 d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
624 SE->getByteLength())));
625}
626
627void Sema::HandleAlignedAttribute(Decl *d, const AttributeList *rawAttr) {
628 // check the attribute arguments.
629 if (rawAttr->getNumArgs() > 1) {
630 Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments,
631 std::string("1"));
632 return;
633 }
634
635 unsigned Align = 0;
636
637 if (rawAttr->getNumArgs() == 0) {
638 // FIXME: This should be the target specific maximum alignment.
639 // (For now we just use 128 bits which is the maximum on X86.
640 Align = 128;
641 return;
642 } else {
643 Expr *alignmentExpr = static_cast<Expr *>(rawAttr->getArg(0));
644 llvm::APSInt alignment(32);
645 if (!alignmentExpr->isIntegerConstantExpr(alignment, Context)) {
646 Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int,
647 "aligned", alignmentExpr->getSourceRange());
648 return;
649 }
650
651 Align = alignment.getZExtValue() * 8;
652 }
653
654 d->addAttr(new AlignedAttr(Align));
655}