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