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