SemaDeclAttr.cpp revision 6953a07ea8765b738eb663867b06a47f8ad245e3
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 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} 656