SemaDeclAttr.cpp revision acc5f3e42334525bf28c86471551f83dfce222d5
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 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 411 if (!Fn) { 412 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 413 "destructor", "function"); 414 return; 415 } 416 417 d->addAttr(new DestructorAttr(priority)); 418} 419 420static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 421 // check the attribute arguments. 422 if (Attr.getNumArgs() != 0) { 423 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 424 std::string("0")); 425 return; 426 } 427 428 d->addAttr(new DeprecatedAttr()); 429} 430 431static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 432 // check the attribute arguments. 433 if (Attr.getNumArgs() != 1) { 434 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 435 std::string("1")); 436 return; 437 } 438 439 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 440 Arg = Arg->IgnoreParenCasts(); 441 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 442 443 if (Str == 0 || Str->isWide()) { 444 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 445 "visibility", std::string("1")); 446 return; 447 } 448 449 const char *TypeStr = Str->getStrData(); 450 unsigned TypeLen = Str->getByteLength(); 451 VisibilityAttr::VisibilityTypes type; 452 453 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 454 type = VisibilityAttr::DefaultVisibility; 455 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 456 type = VisibilityAttr::HiddenVisibility; 457 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 458 type = VisibilityAttr::HiddenVisibility; // FIXME 459 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 460 type = VisibilityAttr::ProtectedVisibility; 461 else { 462 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 463 "visibility", TypeStr); 464 return; 465 } 466 467 d->addAttr(new VisibilityAttr(type)); 468} 469 470static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) { 471 // check the attribute arguments. 472 if (Attr.getNumArgs() != 0) { 473 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 474 std::string("0")); 475 return; 476 } 477 478 d->addAttr(new WeakAttr()); 479} 480 481static void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 482 // check the attribute arguments. 483 if (Attr.getNumArgs() != 0) { 484 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 485 std::string("0")); 486 return; 487 } 488 489 d->addAttr(new DLLImportAttr()); 490} 491 492static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 493 // check the attribute arguments. 494 if (Attr.getNumArgs() != 0) { 495 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 496 std::string("0")); 497 return; 498 } 499 500 d->addAttr(new DLLExportAttr()); 501} 502 503static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 504 // check the attribute arguments. 505 if (Attr.getNumArgs() != 0) { 506 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 507 std::string("0")); 508 return; 509 } 510 511 d->addAttr(new StdCallAttr()); 512} 513 514static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 515 // check the attribute arguments. 516 if (Attr.getNumArgs() != 0) { 517 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 518 std::string("0")); 519 return; 520 } 521 522 d->addAttr(new FastCallAttr()); 523} 524 525static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 526 // check the attribute arguments. 527 if (Attr.getNumArgs() != 0) { 528 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 529 std::string("0")); 530 return; 531 } 532 533 d->addAttr(new NoThrowAttr()); 534} 535 536/// Handle __attribute__((format(type,idx,firstarg))) attributes 537/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 538static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 539 540 if (!Attr.getParameterName()) { 541 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 542 "format", std::string("1")); 543 return; 544 } 545 546 if (Attr.getNumArgs() != 2) { 547 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 548 std::string("3")); 549 return; 550 } 551 552 // GCC ignores the format attribute on K&R style function 553 // prototypes, so we ignore it as well 554 const FunctionTypeProto *proto = getFunctionProto(d); 555 556 if (!proto) { 557 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 558 "format", "function"); 559 return; 560 } 561 562 // FIXME: in C++ the implicit 'this' function parameter also counts. 563 // this is needed in order to be compatible with GCC 564 // the index must start in 1 and the limit is numargs+1 565 unsigned NumArgs = proto->getNumArgs(); 566 unsigned FirstIdx = 1; 567 568 const char *Format = Attr.getParameterName()->getName(); 569 unsigned FormatLen = Attr.getParameterName()->getLength(); 570 571 // Normalize the argument, __foo__ becomes foo. 572 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 573 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 574 Format += 2; 575 FormatLen -= 4; 576 } 577 578 bool Supported = false; 579 bool is_NSString = false; 580 bool is_strftime = false; 581 582 switch (FormatLen) { 583 default: break; 584 case 5: Supported = !memcmp(Format, "scanf", 5); break; 585 case 6: Supported = !memcmp(Format, "printf", 6); break; 586 case 7: Supported = !memcmp(Format, "strfmon", 7); break; 587 case 8: 588 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 589 (is_NSString = !memcmp(Format, "NSString", 8)); 590 break; 591 } 592 593 if (!Supported) { 594 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 595 "format", Attr.getParameterName()->getName()); 596 return; 597 } 598 599 // checks for the 2nd argument 600 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 601 llvm::APSInt Idx(32); 602 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 603 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 604 "format", std::string("2"), IdxExpr->getSourceRange()); 605 return; 606 } 607 608 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 609 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 610 "format", std::string("2"), IdxExpr->getSourceRange()); 611 return; 612 } 613 614 // FIXME: Do we need to bounds check? 615 unsigned ArgIdx = Idx.getZExtValue() - 1; 616 617 // make sure the format string is really a string 618 QualType Ty = proto->getArgType(ArgIdx); 619 620 if (is_NSString) { 621 // FIXME: do we need to check if the type is NSString*? What are 622 // the semantics? 623 if (!isNSStringType(Ty, S.Context)) { 624 // FIXME: Should highlight the actual expression that has the 625 // wrong type. 626 S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString, 627 IdxExpr->getSourceRange()); 628 return; 629 } 630 } else if (!Ty->isPointerType() || 631 !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 632 // FIXME: Should highlight the actual expression that has the 633 // wrong type. 634 S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string, 635 IdxExpr->getSourceRange()); 636 return; 637 } 638 639 // check the 3rd argument 640 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 641 llvm::APSInt FirstArg(32); 642 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 643 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 644 "format", std::string("3"), FirstArgExpr->getSourceRange()); 645 return; 646 } 647 648 // check if the function is variadic if the 3rd argument non-zero 649 if (FirstArg != 0) { 650 if (proto->isVariadic()) { 651 ++NumArgs; // +1 for ... 652 } else { 653 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 654 return; 655 } 656 } 657 658 // strftime requires FirstArg to be 0 because it doesn't read from any variable 659 // the input is just the current time + the format string 660 if (is_strftime) { 661 if (FirstArg != 0) { 662 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter, 663 FirstArgExpr->getSourceRange()); 664 return; 665 } 666 // if 0 it disables parameter checking (to use with e.g. va_list) 667 } else if (FirstArg != 0 && FirstArg != NumArgs) { 668 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 669 "format", std::string("3"), FirstArgExpr->getSourceRange()); 670 return; 671 } 672 673 d->addAttr(new FormatAttr(std::string(Format, FormatLen), 674 Idx.getZExtValue(), FirstArg.getZExtValue())); 675} 676 677static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 678 Sema &S) { 679 // check the attribute arguments. 680 if (Attr.getNumArgs() != 0) { 681 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 682 std::string("0")); 683 return; 684 } 685 686 TypeDecl *decl = dyn_cast<TypeDecl>(d); 687 688 if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) { 689 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 690 "transparent_union", "union"); 691 return; 692 } 693 694 //QualType QTy = Context.getTypeDeclType(decl); 695 //const RecordType *Ty = QTy->getAsUnionType(); 696 697// FIXME 698// Ty->addAttr(new TransparentUnionAttr()); 699} 700 701static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 702 // check the attribute arguments. 703 if (Attr.getNumArgs() != 1) { 704 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 705 std::string("1")); 706 return; 707 } 708 Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 709 StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 710 711 // Make sure that there is a string literal as the annotation's single 712 // argument. 713 if (!SE) { 714 S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 715 return; 716 } 717 d->addAttr(new AnnotateAttr(std::string(SE->getStrData(), 718 SE->getByteLength()))); 719} 720 721static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 722 // check the attribute arguments. 723 if (Attr.getNumArgs() > 1) { 724 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 725 std::string("1")); 726 return; 727 } 728 729 unsigned Align = 0; 730 if (Attr.getNumArgs() == 0) { 731 // FIXME: This should be the target specific maximum alignment. 732 // (For now we just use 128 bits which is the maximum on X86. 733 Align = 128; 734 return; 735 } 736 737 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 738 llvm::APSInt Alignment(32); 739 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 740 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 741 "aligned", alignmentExpr->getSourceRange()); 742 return; 743 } 744 d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8)); 745} 746 747/// HandleModeAttr - This attribute modifies the width of a decl with 748/// primitive type. 749/// 750/// Despite what would be logical, the mode attribute is a decl attribute, 751/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 752/// 'G' be HImode, not an intermediate pointer. 753/// 754static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 755 // This attribute isn't documented, but glibc uses it. It changes 756 // the width of an int or unsigned int to the specified size. 757 758 // Check that there aren't any arguments 759 if (Attr.getNumArgs() != 0) { 760 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 761 std::string("0")); 762 return; 763 } 764 765 IdentifierInfo *Name = Attr.getParameterName(); 766 if (!Name) { 767 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 768 return; 769 } 770 const char *Str = Name->getName(); 771 unsigned Len = Name->getLength(); 772 773 // Normalize the attribute name, __foo__ becomes foo. 774 if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 775 Str[Len - 2] == '_' && Str[Len - 1] == '_') { 776 Str += 2; 777 Len -= 4; 778 } 779 780 unsigned DestWidth = 0; 781 bool IntegerMode = true; 782 switch (Len) { 783 case 2: 784 if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; } 785 if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; } 786 if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; } 787 if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; } 788 if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; } 789 if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; } 790 if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; } 791 if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; } 792 if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; } 793 break; 794 case 4: 795 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 796 // pointer on PIC16 and other embedded platforms. 797 if (!memcmp(Str, "word", 4)) 798 DestWidth = S.Context.Target.getPointerWidth(0); 799 if (!memcmp(Str, "byte", 4)) 800 DestWidth = S.Context.Target.getCharWidth(); 801 break; 802 case 7: 803 if (!memcmp(Str, "pointer", 7)) 804 DestWidth = S.Context.Target.getPointerWidth(0); 805 break; 806 } 807 808 QualType OldTy; 809 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 810 OldTy = TD->getUnderlyingType(); 811 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 812 OldTy = VD->getType(); 813 else { 814 S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode", 815 SourceRange(Attr.getLoc(), Attr.getLoc())); 816 return; 817 } 818 819 // FIXME: Need proper fixed-width types 820 QualType NewTy; 821 switch (DestWidth) { 822 case 0: 823 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName()); 824 return; 825 default: 826 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName()); 827 return; 828 case 8: 829 assert(IntegerMode); 830 if (OldTy->isSignedIntegerType()) 831 NewTy = S.Context.SignedCharTy; 832 else 833 NewTy = S.Context.UnsignedCharTy; 834 break; 835 case 16: 836 assert(IntegerMode); 837 if (OldTy->isSignedIntegerType()) 838 NewTy = S.Context.ShortTy; 839 else 840 NewTy = S.Context.UnsignedShortTy; 841 break; 842 case 32: 843 if (!IntegerMode) 844 NewTy = S.Context.FloatTy; 845 else if (OldTy->isSignedIntegerType()) 846 NewTy = S.Context.IntTy; 847 else 848 NewTy = S.Context.UnsignedIntTy; 849 break; 850 case 64: 851 if (!IntegerMode) 852 NewTy = S.Context.DoubleTy; 853 else if (OldTy->isSignedIntegerType()) 854 NewTy = S.Context.LongLongTy; 855 else 856 NewTy = S.Context.UnsignedLongLongTy; 857 break; 858 } 859 860 if (!OldTy->getAsBuiltinType()) 861 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 862 else if (!(IntegerMode && OldTy->isIntegerType()) && 863 !(!IntegerMode && OldTy->isFloatingType())) { 864 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 865 } 866 867 // Install the new type. 868 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 869 TD->setUnderlyingType(NewTy); 870 else 871 cast<ValueDecl>(D)->setType(NewTy); 872} 873 874//===----------------------------------------------------------------------===// 875// Top Level Sema Entry Points 876//===----------------------------------------------------------------------===// 877 878/// HandleDeclAttribute - Apply the specific attribute to the specified decl if 879/// the attribute applies to decls. If the attribute is a type attribute, just 880/// silently ignore it. 881static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 882 switch (Attr.getKind()) { 883 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 884 case AttributeList::AT_address_space: 885 // Ignore this, this is a type attribute, handled by ProcessTypeAttributes. 886 break; 887 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 888 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 889 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 890 case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 891 case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 892 case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 893 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 894 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 895 case AttributeList::AT_ext_vector_type: 896 HandleExtVectorTypeAttr(D, Attr, S); 897 break; 898 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 899 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 900 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 901 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 902 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 903 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 904 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 905 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 906 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 907 case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 908 case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 909 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 910 case AttributeList::AT_transparent_union: 911 HandleTransparentUnionAttr(D, Attr, S); 912 break; 913 default: 914#if 0 915 // TODO: when we have the full set of attributes, warn about unknown ones. 916 S.Diag(Attr->getLoc(), diag::warn_attribute_ignored, 917 Attr->getName()->getName()); 918#endif 919 break; 920 } 921} 922 923/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 924/// attribute list to the specified decl, ignoring any type attributes. 925void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 926 while (AttrList) { 927 ProcessDeclAttribute(D, *AttrList, *this); 928 AttrList = AttrList->getNext(); 929 } 930} 931 932 933/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 934/// it, apply them to D. This is a bit tricky because PD can have attributes 935/// specified in many different places, and we need to find and apply them all. 936void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 937 // Apply decl attributes from the DeclSpec if present. 938 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 939 ProcessDeclAttributeList(D, Attrs); 940 941 // Walk the declarator structure, applying decl attributes that were in a type 942 // position to the decl itself. This handles cases like: 943 // int *__attr__(x)** D; 944 // when X is a decl attribute. 945 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 946 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 947 ProcessDeclAttributeList(D, Attrs); 948 949 // Finally, apply any attributes on the decl itself. 950 if (const AttributeList *Attrs = PD.getAttributes()) 951 ProcessDeclAttributeList(D, Attrs); 952} 953 954