SemaDeclAttr.cpp revision e1cecbae5d675d1c9abdd9be8fb4e915139de509
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 continue; 286 } 287 288 NonNullArgs.push_back(x); 289 } 290 291 // If no arguments were specified to __attribute__((nonnull)) then all 292 // pointer arguments have a nonnull attribute. 293 if (NonNullArgs.empty()) { 294 unsigned idx = 0; 295 296 for (FunctionTypeProto::arg_type_iterator 297 I=proto->arg_type_begin(), E=proto->arg_type_end(); I!=E; ++I, ++idx) 298 if ((*I)->isPointerType()) 299 NonNullArgs.push_back(idx); 300 301 if (NonNullArgs.empty()) { 302 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 303 return; 304 } 305 } 306 307 unsigned* start = &NonNullArgs[0]; 308 unsigned size = NonNullArgs.size(); 309 std::sort(start, start + size); 310 d->addAttr(new NonNullAttr(start, size)); 311} 312 313static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 314 // check the attribute arguments. 315 if (Attr.getNumArgs() != 1) { 316 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 317 std::string("1")); 318 return; 319 } 320 321 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 322 Arg = Arg->IgnoreParenCasts(); 323 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 324 325 if (Str == 0 || Str->isWide()) { 326 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 327 "alias", std::string("1")); 328 return; 329 } 330 331 const char *Alias = Str->getStrData(); 332 unsigned AliasLen = Str->getByteLength(); 333 334 // FIXME: check if target symbol exists in current file 335 336 d->addAttr(new AliasAttr(std::string(Alias, AliasLen))); 337} 338 339static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 340 // check the attribute arguments. 341 if (Attr.getNumArgs() != 0) { 342 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 343 std::string("0")); 344 return; 345 } 346 347 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 348 if (!Fn) { 349 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 350 "noreturn", "function"); 351 return; 352 } 353 354 d->addAttr(new NoReturnAttr()); 355} 356 357static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 358 // check the attribute arguments. 359 if (Attr.getNumArgs() != 0) { 360 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 361 std::string("0")); 362 return; 363 } 364 365 if (!isa<VarDecl>(d) && !getFunctionProto(d)) { 366 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 367 "unused", "variable and function"); 368 return; 369 } 370 371 d->addAttr(new UnusedAttr()); 372} 373 374static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 375 // check the attribute arguments. 376 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 377 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1"); 378 return; 379 } 380 381 int priority = 65535; // FIXME: Do not hardcode such constants. 382 if (Attr.getNumArgs() > 0) { 383 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 384 llvm::APSInt Idx(32); 385 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 386 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 387 "constructor", "1", E->getSourceRange()); 388 return; 389 } 390 priority = Idx.getZExtValue(); 391 } 392 393 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 394 if (!Fn) { 395 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 396 "constructor", "function"); 397 return; 398 } 399 400 d->addAttr(new ConstructorAttr(priority)); 401} 402 403static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 404 // check the attribute arguments. 405 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 406 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1"); 407 return; 408 } 409 410 int priority = 65535; // FIXME: Do not hardcode such constants. 411 if (Attr.getNumArgs() > 0) { 412 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 413 llvm::APSInt Idx(32); 414 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 415 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 416 "destructor", "1", E->getSourceRange()); 417 return; 418 } 419 priority = Idx.getZExtValue(); 420 } 421 422 if (!isa<FunctionDecl>(d)) { 423 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 424 "destructor", "function"); 425 return; 426 } 427 428 d->addAttr(new DestructorAttr(priority)); 429} 430 431static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 432 // check the attribute arguments. 433 if (Attr.getNumArgs() != 0) { 434 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 435 std::string("0")); 436 return; 437 } 438 439 d->addAttr(new DeprecatedAttr()); 440} 441 442static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 443 // check the attribute arguments. 444 if (Attr.getNumArgs() != 1) { 445 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 446 std::string("1")); 447 return; 448 } 449 450 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 451 Arg = Arg->IgnoreParenCasts(); 452 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 453 454 if (Str == 0 || Str->isWide()) { 455 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 456 "visibility", std::string("1")); 457 return; 458 } 459 460 const char *TypeStr = Str->getStrData(); 461 unsigned TypeLen = Str->getByteLength(); 462 VisibilityAttr::VisibilityTypes type; 463 464 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 465 type = VisibilityAttr::DefaultVisibility; 466 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 467 type = VisibilityAttr::HiddenVisibility; 468 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 469 type = VisibilityAttr::HiddenVisibility; // FIXME 470 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 471 type = VisibilityAttr::ProtectedVisibility; 472 else { 473 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 474 "visibility", TypeStr); 475 return; 476 } 477 478 d->addAttr(new VisibilityAttr(type)); 479} 480 481static void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) { 482 if (!Attr.getParameterName()) { 483 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 484 "objc_gc", std::string("1")); 485 return; 486 } 487 488 if (Attr.getNumArgs() != 0) { 489 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 490 std::string("1")); 491 return; 492 } 493 494 const char *TypeStr = Attr.getParameterName()->getName(); 495 unsigned TypeLen = Attr.getParameterName()->getLength(); 496 497 ObjCGCAttr::GCAttrTypes type; 498 499 if (TypeLen == 4 && !memcmp(TypeStr, "weak", 4)) 500 type = ObjCGCAttr::Weak; 501 else if (TypeLen == 6 && !memcmp(TypeStr, "strong", 6)) 502 type = ObjCGCAttr::Strong; 503 else { 504 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 505 "objc_gc", TypeStr); 506 return; 507 } 508 509 d->addAttr(new ObjCGCAttr(type)); 510} 511 512static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 513 if (!Attr.getParameterName()) { 514 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 515 "blocks", std::string("1")); 516 return; 517 } 518 519 if (Attr.getNumArgs() != 0) { 520 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 521 std::string("1")); 522 return; 523 } 524 const char *TypeStr = Attr.getParameterName()->getName(); 525 unsigned TypeLen = Attr.getParameterName()->getLength(); 526 527 BlocksAttr::BlocksAttrTypes type; 528 529 if (TypeLen == 5 && !memcmp(TypeStr, "byref", 5)) 530 type = BlocksAttr::ByRef; 531 else { 532 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 533 "blocks", TypeStr); 534 return; 535 } 536 537 d->addAttr(new BlocksAttr(type)); 538} 539 540static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) { 541 // check the attribute arguments. 542 if (Attr.getNumArgs() != 0) { 543 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 544 std::string("0")); 545 return; 546 } 547 548 d->addAttr(new WeakAttr()); 549} 550 551static void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 552 // check the attribute arguments. 553 if (Attr.getNumArgs() != 0) { 554 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 555 std::string("0")); 556 return; 557 } 558 559 d->addAttr(new DLLImportAttr()); 560} 561 562static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 563 // check the attribute arguments. 564 if (Attr.getNumArgs() != 0) { 565 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 566 std::string("0")); 567 return; 568 } 569 570 d->addAttr(new DLLExportAttr()); 571} 572 573static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 574 // check the attribute arguments. 575 if (Attr.getNumArgs() != 0) { 576 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 577 std::string("0")); 578 return; 579 } 580 581 d->addAttr(new StdCallAttr()); 582} 583 584static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 585 // check the attribute arguments. 586 if (Attr.getNumArgs() != 0) { 587 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 588 std::string("0")); 589 return; 590 } 591 592 d->addAttr(new FastCallAttr()); 593} 594 595static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 596 // check the attribute arguments. 597 if (Attr.getNumArgs() != 0) { 598 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 599 std::string("0")); 600 return; 601 } 602 603 d->addAttr(new NoThrowAttr()); 604} 605 606/// Handle __attribute__((format(type,idx,firstarg))) attributes 607/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 608static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 609 610 if (!Attr.getParameterName()) { 611 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 612 "format", std::string("1")); 613 return; 614 } 615 616 if (Attr.getNumArgs() != 2) { 617 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 618 std::string("3")); 619 return; 620 } 621 622 // GCC ignores the format attribute on K&R style function 623 // prototypes, so we ignore it as well 624 const FunctionTypeProto *proto = getFunctionProto(d); 625 626 if (!proto) { 627 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 628 "format", "function"); 629 return; 630 } 631 632 // FIXME: in C++ the implicit 'this' function parameter also counts. 633 // this is needed in order to be compatible with GCC 634 // the index must start in 1 and the limit is numargs+1 635 unsigned NumArgs = proto->getNumArgs(); 636 unsigned FirstIdx = 1; 637 638 const char *Format = Attr.getParameterName()->getName(); 639 unsigned FormatLen = Attr.getParameterName()->getLength(); 640 641 // Normalize the argument, __foo__ becomes foo. 642 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 643 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 644 Format += 2; 645 FormatLen -= 4; 646 } 647 648 bool Supported = false; 649 bool is_NSString = false; 650 bool is_strftime = false; 651 652 switch (FormatLen) { 653 default: break; 654 case 5: Supported = !memcmp(Format, "scanf", 5); break; 655 case 6: Supported = !memcmp(Format, "printf", 6); break; 656 case 7: Supported = !memcmp(Format, "strfmon", 7); break; 657 case 8: 658 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 659 (is_NSString = !memcmp(Format, "NSString", 8)); 660 break; 661 } 662 663 if (!Supported) { 664 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 665 "format", Attr.getParameterName()->getName()); 666 return; 667 } 668 669 // checks for the 2nd argument 670 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 671 llvm::APSInt Idx(32); 672 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 673 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 674 "format", std::string("2"), IdxExpr->getSourceRange()); 675 return; 676 } 677 678 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 679 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 680 "format", std::string("2"), IdxExpr->getSourceRange()); 681 return; 682 } 683 684 // FIXME: Do we need to bounds check? 685 unsigned ArgIdx = Idx.getZExtValue() - 1; 686 687 // make sure the format string is really a string 688 QualType Ty = proto->getArgType(ArgIdx); 689 690 if (is_NSString) { 691 // FIXME: do we need to check if the type is NSString*? What are 692 // the semantics? 693 if (!isNSStringType(Ty, S.Context)) { 694 // FIXME: Should highlight the actual expression that has the 695 // wrong type. 696 S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString, 697 IdxExpr->getSourceRange()); 698 return; 699 } 700 } else if (!Ty->isPointerType() || 701 !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 702 // FIXME: Should highlight the actual expression that has the 703 // wrong type. 704 S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string, 705 IdxExpr->getSourceRange()); 706 return; 707 } 708 709 // check the 3rd argument 710 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 711 llvm::APSInt FirstArg(32); 712 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 713 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 714 "format", std::string("3"), FirstArgExpr->getSourceRange()); 715 return; 716 } 717 718 // check if the function is variadic if the 3rd argument non-zero 719 if (FirstArg != 0) { 720 if (proto->isVariadic()) { 721 ++NumArgs; // +1 for ... 722 } else { 723 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 724 return; 725 } 726 } 727 728 // strftime requires FirstArg to be 0 because it doesn't read from any variable 729 // the input is just the current time + the format string 730 if (is_strftime) { 731 if (FirstArg != 0) { 732 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter, 733 FirstArgExpr->getSourceRange()); 734 return; 735 } 736 // if 0 it disables parameter checking (to use with e.g. va_list) 737 } else if (FirstArg != 0 && FirstArg != NumArgs) { 738 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 739 "format", std::string("3"), FirstArgExpr->getSourceRange()); 740 return; 741 } 742 743 d->addAttr(new FormatAttr(std::string(Format, FormatLen), 744 Idx.getZExtValue(), FirstArg.getZExtValue())); 745} 746 747static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 748 Sema &S) { 749 // check the attribute arguments. 750 if (Attr.getNumArgs() != 0) { 751 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 752 std::string("0")); 753 return; 754 } 755 756 // FIXME: This shouldn't be restricted to typedefs 757 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 758 if (!TD || !TD->getUnderlyingType()->isUnionType()) { 759 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 760 "transparent_union", "union"); 761 return; 762 } 763 764 RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 765 766 // FIXME: Should we do a check for RD->isDefinition()? 767 768 // FIXME: This isn't supposed to be restricted to pointers, but otherwise 769 // we might silently generate incorrect code; see following code 770 for (int i = 0; i < RD->getNumMembers(); i++) { 771 if (!RD->getMember(i)->getType()->isPointerType()) { 772 S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer); 773 return; 774 } 775 } 776 777 // FIXME: This is a complete hack; we should be properly propagating 778 // transparent_union through Sema. That said, this is close enough to 779 // correctly compile all the common cases of transparent_union without 780 // errors or warnings 781 QualType NewTy = S.Context.VoidPtrTy; 782 NewTy.addConst(); 783 TD->setUnderlyingType(NewTy); 784} 785 786static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 787 // check the attribute arguments. 788 if (Attr.getNumArgs() != 1) { 789 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 790 std::string("1")); 791 return; 792 } 793 Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 794 StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 795 796 // Make sure that there is a string literal as the annotation's single 797 // argument. 798 if (!SE) { 799 S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 800 return; 801 } 802 d->addAttr(new AnnotateAttr(std::string(SE->getStrData(), 803 SE->getByteLength()))); 804} 805 806static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 807 // check the attribute arguments. 808 if (Attr.getNumArgs() > 1) { 809 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 810 std::string("1")); 811 return; 812 } 813 814 unsigned Align = 0; 815 if (Attr.getNumArgs() == 0) { 816 // FIXME: This should be the target specific maximum alignment. 817 // (For now we just use 128 bits which is the maximum on X86. 818 Align = 128; 819 return; 820 } 821 822 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 823 llvm::APSInt Alignment(32); 824 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 825 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 826 "aligned", alignmentExpr->getSourceRange()); 827 return; 828 } 829 d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8)); 830} 831 832/// HandleModeAttr - This attribute modifies the width of a decl with 833/// primitive type. 834/// 835/// Despite what would be logical, the mode attribute is a decl attribute, 836/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 837/// 'G' be HImode, not an intermediate pointer. 838/// 839static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 840 // This attribute isn't documented, but glibc uses it. It changes 841 // the width of an int or unsigned int to the specified size. 842 843 // Check that there aren't any arguments 844 if (Attr.getNumArgs() != 0) { 845 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 846 std::string("0")); 847 return; 848 } 849 850 IdentifierInfo *Name = Attr.getParameterName(); 851 if (!Name) { 852 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 853 return; 854 } 855 const char *Str = Name->getName(); 856 unsigned Len = Name->getLength(); 857 858 // Normalize the attribute name, __foo__ becomes foo. 859 if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 860 Str[Len - 2] == '_' && Str[Len - 1] == '_') { 861 Str += 2; 862 Len -= 4; 863 } 864 865 unsigned DestWidth = 0; 866 bool IntegerMode = true; 867 switch (Len) { 868 case 2: 869 if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; } 870 if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; } 871 if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; } 872 if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; } 873 if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; } 874 if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; } 875 if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; } 876 if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; } 877 if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; } 878 break; 879 case 4: 880 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 881 // pointer on PIC16 and other embedded platforms. 882 if (!memcmp(Str, "word", 4)) 883 DestWidth = S.Context.Target.getPointerWidth(0); 884 if (!memcmp(Str, "byte", 4)) 885 DestWidth = S.Context.Target.getCharWidth(); 886 break; 887 case 7: 888 if (!memcmp(Str, "pointer", 7)) 889 DestWidth = S.Context.Target.getPointerWidth(0); 890 break; 891 } 892 893 QualType OldTy; 894 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 895 OldTy = TD->getUnderlyingType(); 896 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 897 OldTy = VD->getType(); 898 else { 899 S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode", 900 SourceRange(Attr.getLoc(), Attr.getLoc())); 901 return; 902 } 903 904 // FIXME: Need proper fixed-width types 905 QualType NewTy; 906 switch (DestWidth) { 907 case 0: 908 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName()); 909 return; 910 default: 911 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName()); 912 return; 913 case 8: 914 assert(IntegerMode); 915 if (OldTy->isSignedIntegerType()) 916 NewTy = S.Context.SignedCharTy; 917 else 918 NewTy = S.Context.UnsignedCharTy; 919 break; 920 case 16: 921 assert(IntegerMode); 922 if (OldTy->isSignedIntegerType()) 923 NewTy = S.Context.ShortTy; 924 else 925 NewTy = S.Context.UnsignedShortTy; 926 break; 927 case 32: 928 if (!IntegerMode) 929 NewTy = S.Context.FloatTy; 930 else if (OldTy->isSignedIntegerType()) 931 NewTy = S.Context.IntTy; 932 else 933 NewTy = S.Context.UnsignedIntTy; 934 break; 935 case 64: 936 if (!IntegerMode) 937 NewTy = S.Context.DoubleTy; 938 else if (OldTy->isSignedIntegerType()) 939 NewTy = S.Context.LongLongTy; 940 else 941 NewTy = S.Context.UnsignedLongLongTy; 942 break; 943 } 944 945 if (!OldTy->getAsBuiltinType()) 946 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 947 else if (!(IntegerMode && OldTy->isIntegerType()) && 948 !(!IntegerMode && OldTy->isFloatingType())) { 949 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 950 } 951 952 // Install the new type. 953 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 954 TD->setUnderlyingType(NewTy); 955 else 956 cast<ValueDecl>(D)->setType(NewTy); 957} 958 959//===----------------------------------------------------------------------===// 960// Top Level Sema Entry Points 961//===----------------------------------------------------------------------===// 962 963/// HandleDeclAttribute - Apply the specific attribute to the specified decl if 964/// the attribute applies to decls. If the attribute is a type attribute, just 965/// silently ignore it. 966static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 967 switch (Attr.getKind()) { 968 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 969 case AttributeList::AT_address_space: 970 // Ignore this, this is a type attribute, handled by ProcessTypeAttributes. 971 break; 972 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 973 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 974 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 975 case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 976 case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 977 case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 978 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 979 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 980 case AttributeList::AT_ext_vector_type: 981 HandleExtVectorTypeAttr(D, Attr, S); 982 break; 983 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 984 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 985 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 986 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 987 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 988 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 989 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 990 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 991 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 992 case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 993 case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 994 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 995 case AttributeList::AT_transparent_union: 996 HandleTransparentUnionAttr(D, Attr, S); 997 break; 998 case AttributeList::AT_objc_gc: HandleObjCGCAttr (D, Attr, S); break; 999 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1000 default: 1001#if 0 1002 // TODO: when we have the full set of attributes, warn about unknown ones. 1003 S.Diag(Attr->getLoc(), diag::warn_attribute_ignored, 1004 Attr->getName()->getName()); 1005#endif 1006 break; 1007 } 1008} 1009 1010/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1011/// attribute list to the specified decl, ignoring any type attributes. 1012void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 1013 while (AttrList) { 1014 ProcessDeclAttribute(D, *AttrList, *this); 1015 AttrList = AttrList->getNext(); 1016 } 1017} 1018 1019 1020/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 1021/// it, apply them to D. This is a bit tricky because PD can have attributes 1022/// specified in many different places, and we need to find and apply them all. 1023void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 1024 // Apply decl attributes from the DeclSpec if present. 1025 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 1026 ProcessDeclAttributeList(D, Attrs); 1027 1028 // Walk the declarator structure, applying decl attributes that were in a type 1029 // position to the decl itself. This handles cases like: 1030 // int *__attr__(x)** D; 1031 // when X is a decl attribute. 1032 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 1033 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 1034 ProcessDeclAttributeList(D, Attrs); 1035 1036 // Finally, apply any attributes on the decl itself. 1037 if (const AttributeList *Attrs = PD.getAttributes()) 1038 ProcessDeclAttributeList(D, Attrs); 1039} 1040 1041