SemaDeclAttr.cpp revision 01eb9b9683535d8a65c704ad2c545903409e2d36
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/TargetInfo.h" 19#include "clang/Parse/DeclSpec.h" 20#include "llvm/ADT/StringExtras.h" 21using namespace clang; 22 23//===----------------------------------------------------------------------===// 24// Helper functions 25//===----------------------------------------------------------------------===// 26 27static const FunctionType *getFunctionType(const Decl *d, 28 bool blocksToo = true) { 29 QualType Ty; 30 if (const ValueDecl *decl = dyn_cast<ValueDecl>(d)) 31 Ty = decl->getType(); 32 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d)) 33 Ty = decl->getType(); 34 else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 35 Ty = decl->getUnderlyingType(); 36 else 37 return 0; 38 39 if (Ty->isFunctionPointerType()) 40 Ty = Ty->getAs<PointerType>()->getPointeeType(); 41 else if (blocksToo && Ty->isBlockPointerType()) 42 Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 43 44 return Ty->getAs<FunctionType>(); 45} 46 47// FIXME: We should provide an abstraction around a method or function 48// to provide the following bits of information. 49 50/// isFunctionOrMethod - Return true if the given decl has function 51/// type (function or function-typed variable). 52static bool isFunction(const Decl *d) { 53 return getFunctionType(d, false) != NULL; 54} 55 56/// isFunctionOrMethod - Return true if the given decl has function 57/// type (function or function-typed variable) or an Objective-C 58/// method. 59static bool isFunctionOrMethod(const Decl *d) { 60 return isFunction(d)|| isa<ObjCMethodDecl>(d); 61} 62 63/// isFunctionOrMethodOrBlock - Return true if the given decl has function 64/// type (function or function-typed variable) or an Objective-C 65/// method or a block. 66static bool isFunctionOrMethodOrBlock(const Decl *d) { 67 if (isFunctionOrMethod(d)) 68 return true; 69 // check for block is more involved. 70 if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 71 QualType Ty = V->getType(); 72 return Ty->isBlockPointerType(); 73 } 74 return isa<BlockDecl>(d); 75} 76 77/// hasFunctionProto - Return true if the given decl has a argument 78/// information. This decl should have already passed 79/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 80static bool hasFunctionProto(const Decl *d) { 81 if (const FunctionType *FnTy = getFunctionType(d)) 82 return isa<FunctionProtoType>(FnTy); 83 else { 84 assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 85 return true; 86 } 87} 88 89/// getFunctionOrMethodNumArgs - Return number of function or method 90/// arguments. It is an error to call this on a K&R function (use 91/// hasFunctionProto first). 92static unsigned getFunctionOrMethodNumArgs(const Decl *d) { 93 if (const FunctionType *FnTy = getFunctionType(d)) 94 return cast<FunctionProtoType>(FnTy)->getNumArgs(); 95 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 96 return BD->getNumParams(); 97 return cast<ObjCMethodDecl>(d)->param_size(); 98} 99 100static QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) { 101 if (const FunctionType *FnTy = getFunctionType(d)) 102 return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 103 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 104 return BD->getParamDecl(Idx)->getType(); 105 106 return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 107} 108 109static QualType getFunctionOrMethodResultType(const Decl *d) { 110 if (const FunctionType *FnTy = getFunctionType(d)) 111 return cast<FunctionProtoType>(FnTy)->getResultType(); 112 return cast<ObjCMethodDecl>(d)->getResultType(); 113} 114 115static bool isFunctionOrMethodVariadic(const Decl *d) { 116 if (const FunctionType *FnTy = getFunctionType(d)) { 117 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 118 return proto->isVariadic(); 119 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 120 return BD->IsVariadic(); 121 else { 122 return cast<ObjCMethodDecl>(d)->isVariadic(); 123 } 124} 125 126static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 127 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 128 if (!PT) 129 return false; 130 131 const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAs<ObjCInterfaceType>(); 132 if (!ClsT) 133 return false; 134 135 IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 136 137 // FIXME: Should we walk the chain of classes? 138 return ClsName == &Ctx.Idents.get("NSString") || 139 ClsName == &Ctx.Idents.get("NSMutableString"); 140} 141 142static inline bool isCFStringType(QualType T, ASTContext &Ctx) { 143 const PointerType *PT = T->getAs<PointerType>(); 144 if (!PT) 145 return false; 146 147 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 148 if (!RT) 149 return false; 150 151 const RecordDecl *RD = RT->getDecl(); 152 if (RD->getTagKind() != TagDecl::TK_struct) 153 return false; 154 155 return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 156} 157 158//===----------------------------------------------------------------------===// 159// Attribute Implementations 160//===----------------------------------------------------------------------===// 161 162// FIXME: All this manual attribute parsing code is gross. At the 163// least add some helper functions to check most argument patterns (# 164// and types of args). 165 166static void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 167 const AttributeList &Attr, Sema &S) { 168 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 169 if (tDecl == 0) { 170 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 171 return; 172 } 173 174 QualType curType = tDecl->getUnderlyingType(); 175 176 Expr *sizeExpr; 177 178 // Special case where the argument is a template id. 179 if (Attr.getParameterName()) { 180 sizeExpr = S.ActOnDeclarationNameExpr(scope, Attr.getLoc(), 181 Attr.getParameterName(), 182 false, 0, false).takeAs<Expr>(); 183 } else { 184 // check the attribute arguments. 185 if (Attr.getNumArgs() != 1) { 186 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 187 return; 188 } 189 sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 190 } 191 192 // Instantiate/Install the vector type, and let Sema build the type for us. 193 // This will run the reguired checks. 194 QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc()); 195 if (!T.isNull()) { 196 tDecl->setUnderlyingType(T); 197 198 // Remember this typedef decl, we will need it later for diagnostics. 199 S.ExtVectorDecls.push_back(tDecl); 200 } 201} 202 203 204/// HandleVectorSizeAttribute - this attribute is only applicable to integral 205/// and float scalars, although arrays, pointers, and function return values are 206/// allowed in conjunction with this construct. Aggregates with this attribute 207/// are invalid, even if they are of the same size as a corresponding scalar. 208/// The raw attribute should contain precisely 1 argument, the vector size for 209/// the variable, measured in bytes. If curType and rawAttr are well formed, 210/// this routine will return a new vector type. 211static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 212 QualType CurType; 213 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 214 CurType = VD->getType(); 215 else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 216 CurType = TD->getUnderlyingType(); 217 else { 218 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 219 << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc()); 220 return; 221 } 222 223 // Check the attribute arugments. 224 if (Attr.getNumArgs() != 1) { 225 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 226 return; 227 } 228 Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 229 llvm::APSInt vecSize(32); 230 if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 231 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 232 << "vector_size" << sizeExpr->getSourceRange(); 233 return; 234 } 235 // navigate to the base type - we need to provide for vector pointers, vector 236 // arrays, and functions returning vectors. 237 if (CurType->isPointerType() || CurType->isArrayType() || 238 CurType->isFunctionType()) { 239 S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType; 240 return; 241 /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 242 do { 243 if (PointerType *PT = dyn_cast<PointerType>(canonType)) 244 canonType = PT->getPointeeType().getTypePtr(); 245 else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 246 canonType = AT->getElementType().getTypePtr(); 247 else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 248 canonType = FT->getResultType().getTypePtr(); 249 } while (canonType->isPointerType() || canonType->isArrayType() || 250 canonType->isFunctionType()); 251 */ 252 } 253 // the base type must be integer or float, and can't already be a vector. 254 if (CurType->isVectorType() || 255 (!CurType->isIntegerType() && !CurType->isRealFloatingType())) { 256 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; 257 return; 258 } 259 unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 260 // vecSize is specified in bytes - convert to bits. 261 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 262 263 // the vector size needs to be an integral multiple of the type size. 264 if (vectorSize % typeSize) { 265 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size) 266 << sizeExpr->getSourceRange(); 267 return; 268 } 269 if (vectorSize == 0) { 270 S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 271 << sizeExpr->getSourceRange(); 272 return; 273 } 274 275 // Success! Instantiate the vector type, the number of elements is > 0, and 276 // not required to be a power of 2, unlike GCC. 277 CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 278 279 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 280 VD->setType(CurType); 281 else 282 cast<TypedefDecl>(D)->setUnderlyingType(CurType); 283} 284 285static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 286 // check the attribute arguments. 287 if (Attr.getNumArgs() > 0) { 288 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 289 return; 290 } 291 292 if (TagDecl *TD = dyn_cast<TagDecl>(d)) 293 TD->addAttr(::new (S.Context) PackedAttr); 294 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 295 // If the alignment is less than or equal to 8 bits, the packed attribute 296 // has no effect. 297 if (!FD->getType()->isIncompleteType() && 298 S.Context.getTypeAlign(FD->getType()) <= 8) 299 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 300 << Attr.getName() << FD->getType(); 301 else 302 FD->addAttr(::new (S.Context) PackedAttr); 303 } else 304 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 305} 306 307static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 308 // check the attribute arguments. 309 if (Attr.getNumArgs() > 0) { 310 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 311 return; 312 } 313 314 // The IBOutlet attribute only applies to instance variables of Objective-C 315 // classes. 316 if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) 317 d->addAttr(::new (S.Context) IBOutletAttr()); 318 else 319 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet); 320} 321 322static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 323 // GCC ignores the nonnull attribute on K&R style function prototypes, so we 324 // ignore it as well 325 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 326 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 327 << Attr.getName() << 0 /*function*/; 328 return; 329 } 330 331 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 332 333 // The nonnull attribute only applies to pointers. 334 llvm::SmallVector<unsigned, 10> NonNullArgs; 335 336 for (AttributeList::arg_iterator I=Attr.arg_begin(), 337 E=Attr.arg_end(); I!=E; ++I) { 338 339 340 // The argument must be an integer constant expression. 341 Expr *Ex = static_cast<Expr *>(*I); 342 llvm::APSInt ArgNum(32); 343 if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 344 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 345 << "nonnull" << Ex->getSourceRange(); 346 return; 347 } 348 349 unsigned x = (unsigned) ArgNum.getZExtValue(); 350 351 if (x < 1 || x > NumArgs) { 352 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 353 << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 354 return; 355 } 356 357 --x; 358 359 // Is the function argument a pointer type? 360 QualType T = getFunctionOrMethodArgType(d, x); 361 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 362 // FIXME: Should also highlight argument in decl. 363 S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 364 << "nonnull" << Ex->getSourceRange(); 365 continue; 366 } 367 368 NonNullArgs.push_back(x); 369 } 370 371 // If no arguments were specified to __attribute__((nonnull)) then all pointer 372 // arguments have a nonnull attribute. 373 if (NonNullArgs.empty()) { 374 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 375 QualType T = getFunctionOrMethodArgType(d, I); 376 if (T->isAnyPointerType() || T->isBlockPointerType()) 377 NonNullArgs.push_back(I); 378 } 379 380 if (NonNullArgs.empty()) { 381 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 382 return; 383 } 384 } 385 386 unsigned* start = &NonNullArgs[0]; 387 unsigned size = NonNullArgs.size(); 388 std::sort(start, start + size); 389 d->addAttr(::new (S.Context) NonNullAttr(start, size)); 390} 391 392static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 393 // check the attribute arguments. 394 if (Attr.getNumArgs() != 1) { 395 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 396 return; 397 } 398 399 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 400 Arg = Arg->IgnoreParenCasts(); 401 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 402 403 if (Str == 0 || Str->isWide()) { 404 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 405 << "alias" << 1; 406 return; 407 } 408 409 const char *Alias = Str->getStrData(); 410 unsigned AliasLen = Str->getByteLength(); 411 412 // FIXME: check if target symbol exists in current file 413 414 d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen))); 415} 416 417static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 418 Sema &S) { 419 // check the attribute arguments. 420 if (Attr.getNumArgs() != 0) { 421 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 422 return; 423 } 424 425 if (!isa<FunctionDecl>(d)) { 426 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 427 << Attr.getName() << 0 /*function*/; 428 return; 429 } 430 431 d->addAttr(::new (S.Context) AlwaysInlineAttr()); 432} 433 434static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 435 // check the attribute arguments. 436 if (Attr.getNumArgs() != 0) { 437 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 438 return; 439 } 440 441 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 442 QualType RetTy = FD->getResultType(); 443 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 444 d->addAttr(::new (S.Context) MallocAttr()); 445 return; 446 } 447 } 448 449 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 450} 451 452static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 453 Sema &S) { 454 // check the attribute arguments. 455 if (Attr.getNumArgs() != 0) { 456 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 457 return false; 458 } 459 460 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 461 ValueDecl *VD = dyn_cast<ValueDecl>(d); 462 if (VD == 0 || !VD->getType()->isBlockPointerType()) { 463 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 464 << Attr.getName() << 0 /*function*/; 465 return false; 466 } 467 } 468 469 return true; 470} 471 472static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 473 if (HandleCommonNoReturnAttr(d, Attr, S)) 474 d->addAttr(::new (S.Context) NoReturnAttr()); 475} 476 477static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 478 Sema &S) { 479 if (HandleCommonNoReturnAttr(d, Attr, S)) 480 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 481} 482 483static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 484 // check the attribute arguments. 485 if (Attr.getNumArgs() != 0) { 486 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 487 return; 488 } 489 490 if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 491 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 492 << Attr.getName() << 2 /*variable and function*/; 493 return; 494 } 495 496 d->addAttr(::new (S.Context) UnusedAttr()); 497} 498 499static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 500 // check the attribute arguments. 501 if (Attr.getNumArgs() != 0) { 502 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 503 return; 504 } 505 506 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 507 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 508 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 509 return; 510 } 511 } else if (!isFunctionOrMethod(d)) { 512 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 513 << Attr.getName() << 2 /*variable and function*/; 514 return; 515 } 516 517 d->addAttr(::new (S.Context) UsedAttr()); 518} 519 520static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 521 // check the attribute arguments. 522 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 523 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 524 << "0 or 1"; 525 return; 526 } 527 528 int priority = 65535; // FIXME: Do not hardcode such constants. 529 if (Attr.getNumArgs() > 0) { 530 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 531 llvm::APSInt Idx(32); 532 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 533 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 534 << "constructor" << 1 << E->getSourceRange(); 535 return; 536 } 537 priority = Idx.getZExtValue(); 538 } 539 540 if (!isa<FunctionDecl>(d)) { 541 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 542 << Attr.getName() << 0 /*function*/; 543 return; 544 } 545 546 d->addAttr(::new (S.Context) ConstructorAttr(priority)); 547} 548 549static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 550 // check the attribute arguments. 551 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 552 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 553 << "0 or 1"; 554 return; 555 } 556 557 int priority = 65535; // FIXME: Do not hardcode such constants. 558 if (Attr.getNumArgs() > 0) { 559 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 560 llvm::APSInt Idx(32); 561 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 562 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 563 << "destructor" << 1 << E->getSourceRange(); 564 return; 565 } 566 priority = Idx.getZExtValue(); 567 } 568 569 if (!isa<FunctionDecl>(d)) { 570 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 571 << Attr.getName() << 0 /*function*/; 572 return; 573 } 574 575 d->addAttr(::new (S.Context) DestructorAttr(priority)); 576} 577 578static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 579 // check the attribute arguments. 580 if (Attr.getNumArgs() != 0) { 581 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 582 return; 583 } 584 585 d->addAttr(::new (S.Context) DeprecatedAttr()); 586} 587 588static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 589 // check the attribute arguments. 590 if (Attr.getNumArgs() != 0) { 591 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 592 return; 593 } 594 595 d->addAttr(::new (S.Context) UnavailableAttr()); 596} 597 598static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 599 // check the attribute arguments. 600 if (Attr.getNumArgs() != 1) { 601 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 602 return; 603 } 604 605 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 606 Arg = Arg->IgnoreParenCasts(); 607 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 608 609 if (Str == 0 || Str->isWide()) { 610 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 611 << "visibility" << 1; 612 return; 613 } 614 615 const char *TypeStr = Str->getStrData(); 616 unsigned TypeLen = Str->getByteLength(); 617 VisibilityAttr::VisibilityTypes type; 618 619 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 620 type = VisibilityAttr::DefaultVisibility; 621 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 622 type = VisibilityAttr::HiddenVisibility; 623 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 624 type = VisibilityAttr::HiddenVisibility; // FIXME 625 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 626 type = VisibilityAttr::ProtectedVisibility; 627 else { 628 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 629 return; 630 } 631 632 d->addAttr(::new (S.Context) VisibilityAttr(type)); 633} 634 635static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 636 Sema &S) { 637 if (Attr.getNumArgs() != 0) { 638 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 639 return; 640 } 641 642 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 643 if (OCI == 0) { 644 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 645 return; 646 } 647 648 D->addAttr(::new (S.Context) ObjCExceptionAttr()); 649} 650 651static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 652 if (Attr.getNumArgs() != 0) { 653 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 654 return; 655 } 656 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 657 QualType T = TD->getUnderlyingType(); 658 if (!T->isPointerType() || 659 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 660 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 661 return; 662 } 663 } 664 D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 665} 666 667static void 668HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 669 if (Attr.getNumArgs() != 0) { 670 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 671 return; 672 } 673 674 if (!isa<FunctionDecl>(D)) { 675 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 676 return; 677 } 678 679 D->addAttr(::new (S.Context) OverloadableAttr()); 680} 681 682static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 683 if (!Attr.getParameterName()) { 684 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 685 << "blocks" << 1; 686 return; 687 } 688 689 if (Attr.getNumArgs() != 0) { 690 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 691 return; 692 } 693 694 BlocksAttr::BlocksAttrTypes type; 695 if (Attr.getParameterName()->isStr("byref")) 696 type = BlocksAttr::ByRef; 697 else { 698 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 699 << "blocks" << Attr.getParameterName(); 700 return; 701 } 702 703 d->addAttr(::new (S.Context) BlocksAttr(type)); 704} 705 706static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 707 // check the attribute arguments. 708 if (Attr.getNumArgs() > 2) { 709 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 710 << "0, 1 or 2"; 711 return; 712 } 713 714 int sentinel = 0; 715 if (Attr.getNumArgs() > 0) { 716 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 717 llvm::APSInt Idx(32); 718 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 719 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 720 << "sentinel" << 1 << E->getSourceRange(); 721 return; 722 } 723 sentinel = Idx.getZExtValue(); 724 725 if (sentinel < 0) { 726 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 727 << E->getSourceRange(); 728 return; 729 } 730 } 731 732 int nullPos = 0; 733 if (Attr.getNumArgs() > 1) { 734 Expr *E = static_cast<Expr *>(Attr.getArg(1)); 735 llvm::APSInt Idx(32); 736 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 737 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 738 << "sentinel" << 2 << E->getSourceRange(); 739 return; 740 } 741 nullPos = Idx.getZExtValue(); 742 743 if (nullPos > 1 || nullPos < 0) { 744 // FIXME: This error message could be improved, it would be nice 745 // to say what the bounds actually are. 746 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 747 << E->getSourceRange(); 748 return; 749 } 750 } 751 752 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 753 const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 754 assert(FT && "FunctionDecl has non-function type?"); 755 756 if (isa<FunctionNoProtoType>(FT)) { 757 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 758 return; 759 } 760 761 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 762 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 763 return; 764 } 765 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 766 if (!MD->isVariadic()) { 767 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 768 return; 769 } 770 } else if (isa<BlockDecl>(d)) { 771 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 772 // caller. 773 ; 774 } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 775 QualType Ty = V->getType(); 776 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 777 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 778 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 779 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 780 int m = Ty->isFunctionPointerType() ? 0 : 1; 781 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 782 return; 783 } 784 } else { 785 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 786 << Attr.getName() << 6 /*function, method or block */; 787 return; 788 } 789 } else { 790 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 791 << Attr.getName() << 6 /*function, method or block */; 792 return; 793 } 794 d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos)); 795} 796 797static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 798 // check the attribute arguments. 799 if (Attr.getNumArgs() != 0) { 800 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 801 return; 802 } 803 804 // TODO: could also be applied to methods? 805 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 806 if (!Fn) { 807 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 808 << Attr.getName() << 0 /*function*/; 809 return; 810 } 811 812 Fn->addAttr(::new (S.Context) WarnUnusedResultAttr()); 813} 814 815static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 816 // check the attribute arguments. 817 if (Attr.getNumArgs() != 0) { 818 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 819 return; 820 } 821 822 /* weak only applies to non-static declarations */ 823 bool isStatic = false; 824 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 825 isStatic = VD->getStorageClass() == VarDecl::Static; 826 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 827 isStatic = FD->getStorageClass() == FunctionDecl::Static; 828 } 829 if (isStatic) { 830 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 831 dyn_cast<NamedDecl>(D)->getNameAsString(); 832 return; 833 } 834 835 // TODO: could also be applied to methods? 836 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 837 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 838 << Attr.getName() << 2 /*variable and function*/; 839 return; 840 } 841 842 D->addAttr(::new (S.Context) WeakAttr()); 843} 844 845static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 846 // check the attribute arguments. 847 if (Attr.getNumArgs() != 0) { 848 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 849 return; 850 } 851 852 // weak_import only applies to variable & function declarations. 853 bool isDef = false; 854 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 855 isDef = (!VD->hasExternalStorage() || VD->getInit()); 856 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 857 isDef = FD->getBody(); 858 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 859 // We ignore weak import on properties and methods 860 return; 861 } else { 862 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 863 << Attr.getName() << 2 /*variable and function*/; 864 return; 865 } 866 867 // Merge should handle any subsequent violations. 868 if (isDef) { 869 S.Diag(Attr.getLoc(), 870 diag::warn_attribute_weak_import_invalid_on_definition) 871 << "weak_import" << 2 /*variable and function*/; 872 return; 873 } 874 875 D->addAttr(::new (S.Context) WeakImportAttr()); 876} 877 878static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 879 // check the attribute arguments. 880 if (Attr.getNumArgs() != 0) { 881 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 882 return; 883 } 884 885 // Attribute can be applied only to functions or variables. 886 if (isa<VarDecl>(D)) { 887 D->addAttr(::new (S.Context) DLLImportAttr()); 888 return; 889 } 890 891 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 892 if (!FD) { 893 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 894 << Attr.getName() << 2 /*variable and function*/; 895 return; 896 } 897 898 // Currently, the dllimport attribute is ignored for inlined functions. 899 // Warning is emitted. 900 if (FD->isInline()) { 901 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 902 return; 903 } 904 905 // The attribute is also overridden by a subsequent declaration as dllexport. 906 // Warning is emitted. 907 for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 908 nextAttr = nextAttr->getNext()) { 909 if (nextAttr->getKind() == AttributeList::AT_dllexport) { 910 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 911 return; 912 } 913 } 914 915 if (D->getAttr<DLLExportAttr>()) { 916 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 917 return; 918 } 919 920 D->addAttr(::new (S.Context) DLLImportAttr()); 921} 922 923static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 924 // check the attribute arguments. 925 if (Attr.getNumArgs() != 0) { 926 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 927 return; 928 } 929 930 // Attribute can be applied only to functions or variables. 931 if (isa<VarDecl>(D)) { 932 D->addAttr(::new (S.Context) DLLExportAttr()); 933 return; 934 } 935 936 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 937 if (!FD) { 938 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 939 << Attr.getName() << 2 /*variable and function*/; 940 return; 941 } 942 943 // Currently, the dllexport attribute is ignored for inlined functions, unless 944 // the -fkeep-inline-functions flag has been used. Warning is emitted; 945 if (FD->isInline()) { 946 // FIXME: ... unless the -fkeep-inline-functions flag has been used. 947 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 948 return; 949 } 950 951 D->addAttr(::new (S.Context) DLLExportAttr()); 952} 953 954static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 955 Sema &S) { 956 // Attribute has 3 arguments. 957 if (Attr.getNumArgs() != 3) { 958 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 959 return; 960 } 961 962 unsigned WGSize[3]; 963 for (unsigned i = 0; i < 3; ++i) { 964 Expr *E = static_cast<Expr *>(Attr.getArg(i)); 965 llvm::APSInt ArgNum(32); 966 if (!E->isIntegerConstantExpr(ArgNum, S.Context)) { 967 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 968 << "reqd_work_group_size" << E->getSourceRange(); 969 return; 970 } 971 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 972 } 973 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], 974 WGSize[2])); 975} 976 977static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 978 // Attribute has no arguments. 979 if (Attr.getNumArgs() != 1) { 980 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 981 return; 982 } 983 984 // Make sure that there is a string literal as the sections's single 985 // argument. 986 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 987 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 988 if (!SE) { 989 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 990 return; 991 } 992 993 std::string SectionStr(SE->getStrData(), SE->getByteLength()); 994 995 // If the target wants to validate the section specifier, make it happen. 996 std::string Error = S.Context.Target.isValidSectionSpecifier(SectionStr); 997 if (Error.empty()) { 998 D->addAttr(::new (S.Context) SectionAttr(SectionStr)); 999 return; 1000 } 1001 1002 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1003 << Error; 1004 1005} 1006 1007static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1008 // Attribute has no arguments. 1009 if (Attr.getNumArgs() != 0) { 1010 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1011 return; 1012 } 1013 1014 // Attribute can be applied only to functions. 1015 if (!isa<FunctionDecl>(d)) { 1016 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1017 << Attr.getName() << 0 /*function*/; 1018 return; 1019 } 1020 1021 // stdcall and fastcall attributes are mutually incompatible. 1022 if (d->getAttr<FastCallAttr>()) { 1023 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1024 << "stdcall" << "fastcall"; 1025 return; 1026 } 1027 1028 d->addAttr(::new (S.Context) StdCallAttr()); 1029} 1030 1031static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1032 // Attribute has no arguments. 1033 if (Attr.getNumArgs() != 0) { 1034 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1035 return; 1036 } 1037 1038 if (!isa<FunctionDecl>(d)) { 1039 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1040 << Attr.getName() << 0 /*function*/; 1041 return; 1042 } 1043 1044 // stdcall and fastcall attributes are mutually incompatible. 1045 if (d->getAttr<StdCallAttr>()) { 1046 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1047 << "fastcall" << "stdcall"; 1048 return; 1049 } 1050 1051 d->addAttr(::new (S.Context) FastCallAttr()); 1052} 1053 1054static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1055 // check the attribute arguments. 1056 if (Attr.getNumArgs() != 0) { 1057 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1058 return; 1059 } 1060 1061 d->addAttr(::new (S.Context) NoThrowAttr()); 1062} 1063 1064static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1065 // check the attribute arguments. 1066 if (Attr.getNumArgs() != 0) { 1067 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1068 return; 1069 } 1070 1071 d->addAttr(::new (S.Context) ConstAttr()); 1072} 1073 1074static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1075 // check the attribute arguments. 1076 if (Attr.getNumArgs() != 0) { 1077 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1078 return; 1079 } 1080 1081 d->addAttr(::new (S.Context) PureAttr()); 1082} 1083 1084static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1085 // Match gcc which ignores cleanup attrs when compiling C++. 1086 if (S.getLangOptions().CPlusPlus) 1087 return; 1088 1089 if (!Attr.getParameterName()) { 1090 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1091 return; 1092 } 1093 1094 if (Attr.getNumArgs() != 0) { 1095 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1096 return; 1097 } 1098 1099 VarDecl *VD = dyn_cast<VarDecl>(d); 1100 1101 if (!VD || !VD->hasLocalStorage()) { 1102 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1103 return; 1104 } 1105 1106 // Look up the function 1107 NamedDecl *CleanupDecl 1108 = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 1109 Sema::LookupOrdinaryName); 1110 if (!CleanupDecl) { 1111 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1112 Attr.getParameterName(); 1113 return; 1114 } 1115 1116 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1117 if (!FD) { 1118 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1119 Attr.getParameterName(); 1120 return; 1121 } 1122 1123 if (FD->getNumParams() != 1) { 1124 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1125 Attr.getParameterName(); 1126 return; 1127 } 1128 1129 // We're currently more strict than GCC about what function types we accept. 1130 // If this ever proves to be a problem it should be easy to fix. 1131 QualType Ty = S.Context.getPointerType(VD->getType()); 1132 QualType ParamTy = FD->getParamDecl(0)->getType(); 1133 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1134 S.Diag(Attr.getLoc(), 1135 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1136 Attr.getParameterName() << ParamTy << Ty; 1137 return; 1138 } 1139 1140 d->addAttr(::new (S.Context) CleanupAttr(FD)); 1141} 1142 1143/// Handle __attribute__((format_arg((idx)))) attribute based on 1144/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1145static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1146 if (Attr.getNumArgs() != 1) { 1147 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1148 return; 1149 } 1150 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1151 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1152 << Attr.getName() << 0 /*function*/; 1153 return; 1154 } 1155 // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1156 // needed in order to be compatible with GCC the index must start with 1. 1157 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1158 unsigned FirstIdx = 1; 1159 // checks for the 2nd argument 1160 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1161 llvm::APSInt Idx(32); 1162 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1163 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1164 << "format" << 2 << IdxExpr->getSourceRange(); 1165 return; 1166 } 1167 1168 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1169 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1170 << "format" << 2 << IdxExpr->getSourceRange(); 1171 return; 1172 } 1173 1174 unsigned ArgIdx = Idx.getZExtValue() - 1; 1175 1176 // make sure the format string is really a string 1177 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1178 1179 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 1180 if (not_nsstring_type && 1181 !isCFStringType(Ty, S.Context) && 1182 (!Ty->isPointerType() || 1183 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1184 // FIXME: Should highlight the actual expression that has the wrong type. 1185 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1186 << (not_nsstring_type ? "a string type" : "an NSString") 1187 << IdxExpr->getSourceRange(); 1188 return; 1189 } 1190 Ty = getFunctionOrMethodResultType(d); 1191 if (!isNSStringType(Ty, S.Context) && 1192 !isCFStringType(Ty, S.Context) && 1193 (!Ty->isPointerType() || 1194 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1195 // FIXME: Should highlight the actual expression that has the wrong type. 1196 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1197 << (not_nsstring_type ? "string type" : "NSString") 1198 << IdxExpr->getSourceRange(); 1199 return; 1200 } 1201 1202 d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); 1203} 1204 1205enum FormatAttrKind { 1206 CFStringFormat, 1207 NSStringFormat, 1208 StrftimeFormat, 1209 SupportedFormat, 1210 InvalidFormat 1211}; 1212 1213/// getFormatAttrKind - Map from format attribute names to supported format 1214/// types. 1215static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 1216 // Check for formats that get handled specially. 1217 if (Format == "NSString") 1218 return NSStringFormat; 1219 if (Format == "CFString") 1220 return CFStringFormat; 1221 if (Format == "strftime") 1222 return StrftimeFormat; 1223 1224 // Otherwise, check for supported formats. 1225 if (Format == "scanf" || Format == "printf" || Format == "printf0" || 1226 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 1227 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 1228 Format == "zcmn_err") 1229 return SupportedFormat; 1230 1231 return InvalidFormat; 1232} 1233 1234/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1235/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1236static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1237 1238 if (!Attr.getParameterName()) { 1239 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1240 << "format" << 1; 1241 return; 1242 } 1243 1244 if (Attr.getNumArgs() != 2) { 1245 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1246 return; 1247 } 1248 1249 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1250 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1251 << Attr.getName() << 0 /*function*/; 1252 return; 1253 } 1254 1255 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1256 unsigned FirstIdx = 1; 1257 1258 llvm::StringRef Format = Attr.getParameterName()->getName(); 1259 1260 // Normalize the argument, __foo__ becomes foo. 1261 if (Format.startswith("__") && Format.endswith("__")) 1262 Format = Format.substr(2, Format.size() - 4); 1263 1264 // Check for supported formats. 1265 FormatAttrKind Kind = getFormatAttrKind(Format); 1266 if (Kind == InvalidFormat) { 1267 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1268 << "format" << Attr.getParameterName()->getName(); 1269 return; 1270 } 1271 1272 // checks for the 2nd argument 1273 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1274 llvm::APSInt Idx(32); 1275 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1276 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1277 << "format" << 2 << IdxExpr->getSourceRange(); 1278 return; 1279 } 1280 1281 // FIXME: We should handle the implicit 'this' parameter in a more generic 1282 // way that can be used for other arguments. 1283 bool HasImplicitThisParam = false; 1284 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 1285 if (MD->isInstance()) { 1286 HasImplicitThisParam = true; 1287 NumArgs++; 1288 } 1289 } 1290 1291 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1292 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1293 << "format" << 2 << IdxExpr->getSourceRange(); 1294 return; 1295 } 1296 1297 // FIXME: Do we need to bounds check? 1298 unsigned ArgIdx = Idx.getZExtValue() - 1; 1299 1300 if (HasImplicitThisParam) ArgIdx--; 1301 1302 // make sure the format string is really a string 1303 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1304 1305 if (Kind == CFStringFormat) { 1306 if (!isCFStringType(Ty, S.Context)) { 1307 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1308 << "a CFString" << IdxExpr->getSourceRange(); 1309 return; 1310 } 1311 } else if (Kind == NSStringFormat) { 1312 // FIXME: do we need to check if the type is NSString*? What are the 1313 // semantics? 1314 if (!isNSStringType(Ty, S.Context)) { 1315 // FIXME: Should highlight the actual expression that has the wrong type. 1316 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1317 << "an NSString" << IdxExpr->getSourceRange(); 1318 return; 1319 } 1320 } else if (!Ty->isPointerType() || 1321 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1322 // FIXME: Should highlight the actual expression that has the wrong type. 1323 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1324 << "a string type" << IdxExpr->getSourceRange(); 1325 return; 1326 } 1327 1328 // check the 3rd argument 1329 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1330 llvm::APSInt FirstArg(32); 1331 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1332 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1333 << "format" << 3 << FirstArgExpr->getSourceRange(); 1334 return; 1335 } 1336 1337 // check if the function is variadic if the 3rd argument non-zero 1338 if (FirstArg != 0) { 1339 if (isFunctionOrMethodVariadic(d)) { 1340 ++NumArgs; // +1 for ... 1341 } else { 1342 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1343 return; 1344 } 1345 } 1346 1347 // strftime requires FirstArg to be 0 because it doesn't read from any 1348 // variable the input is just the current time + the format string. 1349 if (Kind == StrftimeFormat) { 1350 if (FirstArg != 0) { 1351 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1352 << FirstArgExpr->getSourceRange(); 1353 return; 1354 } 1355 // if 0 it disables parameter checking (to use with e.g. va_list) 1356 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1357 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1358 << "format" << 3 << FirstArgExpr->getSourceRange(); 1359 return; 1360 } 1361 1362 d->addAttr(::new (S.Context) FormatAttr(Format, Idx.getZExtValue(), 1363 FirstArg.getZExtValue())); 1364} 1365 1366static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1367 Sema &S) { 1368 // check the attribute arguments. 1369 if (Attr.getNumArgs() != 0) { 1370 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1371 return; 1372 } 1373 1374 // Try to find the underlying union declaration. 1375 RecordDecl *RD = 0; 1376 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1377 if (TD && TD->getUnderlyingType()->isUnionType()) 1378 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1379 else 1380 RD = dyn_cast<RecordDecl>(d); 1381 1382 if (!RD || !RD->isUnion()) { 1383 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1384 << Attr.getName() << 1 /*union*/; 1385 return; 1386 } 1387 1388 if (!RD->isDefinition()) { 1389 S.Diag(Attr.getLoc(), 1390 diag::warn_transparent_union_attribute_not_definition); 1391 return; 1392 } 1393 1394 RecordDecl::field_iterator Field = RD->field_begin(), 1395 FieldEnd = RD->field_end(); 1396 if (Field == FieldEnd) { 1397 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1398 return; 1399 } 1400 1401 FieldDecl *FirstField = *Field; 1402 QualType FirstType = FirstField->getType(); 1403 if (FirstType->isFloatingType() || FirstType->isVectorType()) { 1404 S.Diag(FirstField->getLocation(), 1405 diag::warn_transparent_union_attribute_floating); 1406 return; 1407 } 1408 1409 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1410 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1411 for (; Field != FieldEnd; ++Field) { 1412 QualType FieldType = Field->getType(); 1413 if (S.Context.getTypeSize(FieldType) != FirstSize || 1414 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1415 // Warn if we drop the attribute. 1416 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1417 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1418 : S.Context.getTypeAlign(FieldType); 1419 S.Diag(Field->getLocation(), 1420 diag::warn_transparent_union_attribute_field_size_align) 1421 << isSize << Field->getDeclName() << FieldBits; 1422 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1423 S.Diag(FirstField->getLocation(), 1424 diag::note_transparent_union_first_field_size_align) 1425 << isSize << FirstBits; 1426 return; 1427 } 1428 } 1429 1430 RD->addAttr(::new (S.Context) TransparentUnionAttr()); 1431} 1432 1433static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1434 // check the attribute arguments. 1435 if (Attr.getNumArgs() != 1) { 1436 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1437 return; 1438 } 1439 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1440 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1441 1442 // Make sure that there is a string literal as the annotation's single 1443 // argument. 1444 if (!SE) { 1445 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 1446 return; 1447 } 1448 d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), 1449 SE->getByteLength()))); 1450} 1451 1452static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1453 // check the attribute arguments. 1454 if (Attr.getNumArgs() > 1) { 1455 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1456 return; 1457 } 1458 1459 unsigned Align = 0; 1460 if (Attr.getNumArgs() == 0) { 1461 // FIXME: This should be the target specific maximum alignment. 1462 // (For now we just use 128 bits which is the maximum on X86). 1463 Align = 128; 1464 d->addAttr(::new (S.Context) AlignedAttr(Align)); 1465 return; 1466 } 1467 1468 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 1469 llvm::APSInt Alignment(32); 1470 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1471 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1472 << "aligned" << alignmentExpr->getSourceRange(); 1473 return; 1474 } 1475 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1476 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1477 << alignmentExpr->getSourceRange(); 1478 return; 1479 } 1480 1481 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 1482} 1483 1484/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1485/// type. 1486/// 1487/// Despite what would be logical, the mode attribute is a decl attribute, not a 1488/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1489/// HImode, not an intermediate pointer. 1490static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1491 // This attribute isn't documented, but glibc uses it. It changes 1492 // the width of an int or unsigned int to the specified size. 1493 1494 // Check that there aren't any arguments 1495 if (Attr.getNumArgs() != 0) { 1496 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1497 return; 1498 } 1499 1500 IdentifierInfo *Name = Attr.getParameterName(); 1501 if (!Name) { 1502 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1503 return; 1504 } 1505 1506 llvm::StringRef Str = Attr.getParameterName()->getName(); 1507 1508 // Normalize the attribute name, __foo__ becomes foo. 1509 if (Str.startswith("__") && Str.endswith("__")) 1510 Str = Str.substr(2, Str.size() - 4); 1511 1512 unsigned DestWidth = 0; 1513 bool IntegerMode = true; 1514 bool ComplexMode = false; 1515 switch (Str.size()) { 1516 case 2: 1517 switch (Str[0]) { 1518 case 'Q': DestWidth = 8; break; 1519 case 'H': DestWidth = 16; break; 1520 case 'S': DestWidth = 32; break; 1521 case 'D': DestWidth = 64; break; 1522 case 'X': DestWidth = 96; break; 1523 case 'T': DestWidth = 128; break; 1524 } 1525 if (Str[1] == 'F') { 1526 IntegerMode = false; 1527 } else if (Str[1] == 'C') { 1528 IntegerMode = false; 1529 ComplexMode = true; 1530 } else if (Str[1] != 'I') { 1531 DestWidth = 0; 1532 } 1533 break; 1534 case 4: 1535 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1536 // pointer on PIC16 and other embedded platforms. 1537 if (Str == "word") 1538 DestWidth = S.Context.Target.getPointerWidth(0); 1539 else if (Str == "byte") 1540 DestWidth = S.Context.Target.getCharWidth(); 1541 break; 1542 case 7: 1543 if (Str == "pointer") 1544 DestWidth = S.Context.Target.getPointerWidth(0); 1545 break; 1546 } 1547 1548 QualType OldTy; 1549 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1550 OldTy = TD->getUnderlyingType(); 1551 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1552 OldTy = VD->getType(); 1553 else { 1554 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1555 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1556 return; 1557 } 1558 1559 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 1560 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1561 else if (IntegerMode) { 1562 if (!OldTy->isIntegralType()) 1563 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1564 } else if (ComplexMode) { 1565 if (!OldTy->isComplexType()) 1566 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1567 } else { 1568 if (!OldTy->isFloatingType()) 1569 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1570 } 1571 1572 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1573 // and friends, at least with glibc. 1574 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1575 // width on unusual platforms. 1576 // FIXME: Make sure floating-point mappings are accurate 1577 // FIXME: Support XF and TF types 1578 QualType NewTy; 1579 switch (DestWidth) { 1580 case 0: 1581 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1582 return; 1583 default: 1584 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1585 return; 1586 case 8: 1587 if (!IntegerMode) { 1588 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1589 return; 1590 } 1591 if (OldTy->isSignedIntegerType()) 1592 NewTy = S.Context.SignedCharTy; 1593 else 1594 NewTy = S.Context.UnsignedCharTy; 1595 break; 1596 case 16: 1597 if (!IntegerMode) { 1598 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1599 return; 1600 } 1601 if (OldTy->isSignedIntegerType()) 1602 NewTy = S.Context.ShortTy; 1603 else 1604 NewTy = S.Context.UnsignedShortTy; 1605 break; 1606 case 32: 1607 if (!IntegerMode) 1608 NewTy = S.Context.FloatTy; 1609 else if (OldTy->isSignedIntegerType()) 1610 NewTy = S.Context.IntTy; 1611 else 1612 NewTy = S.Context.UnsignedIntTy; 1613 break; 1614 case 64: 1615 if (!IntegerMode) 1616 NewTy = S.Context.DoubleTy; 1617 else if (OldTy->isSignedIntegerType()) 1618 NewTy = S.Context.LongLongTy; 1619 else 1620 NewTy = S.Context.UnsignedLongLongTy; 1621 break; 1622 case 96: 1623 NewTy = S.Context.LongDoubleTy; 1624 break; 1625 case 128: 1626 if (!IntegerMode) { 1627 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1628 return; 1629 } 1630 NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 1631 break; 1632 } 1633 1634 if (ComplexMode) { 1635 NewTy = S.Context.getComplexType(NewTy); 1636 } 1637 1638 // Install the new type. 1639 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1640 TD->setUnderlyingType(NewTy); 1641 else 1642 cast<ValueDecl>(D)->setType(NewTy); 1643} 1644 1645static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1646 // check the attribute arguments. 1647 if (Attr.getNumArgs() > 0) { 1648 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1649 return; 1650 } 1651 1652 if (!isFunctionOrMethod(d)) { 1653 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1654 << Attr.getName() << 0 /*function*/; 1655 return; 1656 } 1657 1658 d->addAttr(::new (S.Context) NoDebugAttr()); 1659} 1660 1661static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1662 // check the attribute arguments. 1663 if (Attr.getNumArgs() != 0) { 1664 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1665 return; 1666 } 1667 1668 if (!isa<FunctionDecl>(d)) { 1669 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1670 << Attr.getName() << 0 /*function*/; 1671 return; 1672 } 1673 1674 d->addAttr(::new (S.Context) NoInlineAttr()); 1675} 1676 1677static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1678 // check the attribute arguments. 1679 if (Attr.getNumArgs() != 0) { 1680 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1681 return; 1682 } 1683 1684 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1685 if (Fn == 0) { 1686 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1687 << Attr.getName() << 0 /*function*/; 1688 return; 1689 } 1690 1691 if (!Fn->isInline()) { 1692 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1693 return; 1694 } 1695 1696 d->addAttr(::new (S.Context) GNUInlineAttr()); 1697} 1698 1699static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1700 // check the attribute arguments. 1701 if (Attr.getNumArgs() != 1) { 1702 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1703 return; 1704 } 1705 1706 if (!isFunctionOrMethod(d)) { 1707 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1708 << Attr.getName() << 0 /*function*/; 1709 return; 1710 } 1711 1712 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 1713 llvm::APSInt NumParams(32); 1714 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 1715 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1716 << "regparm" << NumParamsExpr->getSourceRange(); 1717 return; 1718 } 1719 1720 if (S.Context.Target.getRegParmMax() == 0) { 1721 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 1722 << NumParamsExpr->getSourceRange(); 1723 return; 1724 } 1725 1726 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1727 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1728 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 1729 return; 1730 } 1731 1732 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1733} 1734 1735//===----------------------------------------------------------------------===// 1736// Checker-specific attribute handlers. 1737//===----------------------------------------------------------------------===// 1738 1739static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1740 Sema &S) { 1741 1742 QualType RetTy; 1743 1744 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 1745 RetTy = MD->getResultType(); 1746 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 1747 RetTy = FD->getResultType(); 1748 else { 1749 SourceLocation L = Attr.getLoc(); 1750 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 1751 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 1752 return; 1753 } 1754 1755 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 1756 || RetTy->getAs<ObjCObjectPointerType>())) { 1757 SourceLocation L = Attr.getLoc(); 1758 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 1759 << SourceRange(L, L) << Attr.getName(); 1760 return; 1761 } 1762 1763 switch (Attr.getKind()) { 1764 default: 1765 assert(0 && "invalid ownership attribute"); 1766 return; 1767 case AttributeList::AT_cf_returns_retained: 1768 d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1769 return; 1770 case AttributeList::AT_ns_returns_retained: 1771 d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1772 return; 1773 }; 1774} 1775 1776//===----------------------------------------------------------------------===// 1777// Top Level Sema Entry Points 1778//===----------------------------------------------------------------------===// 1779 1780/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1781/// the attribute applies to decls. If the attribute is a type attribute, just 1782/// silently ignore it. 1783static void ProcessDeclAttribute(Scope *scope, Decl *D, 1784 const AttributeList &Attr, Sema &S) { 1785 if (Attr.isDeclspecAttribute()) 1786 // FIXME: Try to deal with __declspec attributes! 1787 return; 1788 switch (Attr.getKind()) { 1789 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1790 case AttributeList::AT_address_space: 1791 case AttributeList::AT_objc_gc: 1792 // Ignore these, these are type attributes, handled by 1793 // ProcessTypeAttributes. 1794 break; 1795 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 1796 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1797 case AttributeList::AT_always_inline: 1798 HandleAlwaysInlineAttr (D, Attr, S); break; 1799 case AttributeList::AT_analyzer_noreturn: 1800 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 1801 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 1802 case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1803 case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 1804 case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1805 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 1806 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 1807 case AttributeList::AT_ext_vector_type: 1808 HandleExtVectorTypeAttr(scope, D, Attr, S); 1809 break; 1810 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1811 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1812 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 1813 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(D, Attr, S); break; 1814 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1815 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 1816 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 1817 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 1818 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1819 1820 // Checker-specific. 1821 case AttributeList::AT_ns_returns_retained: 1822 case AttributeList::AT_cf_returns_retained: 1823 HandleNSReturnsRetainedAttr(D, Attr, S); break; 1824 1825 case AttributeList::AT_reqd_wg_size: 1826 HandleReqdWorkGroupSize(D, Attr, S); break; 1827 1828 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 1829 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 1830 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1831 case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 1832 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1833 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 1834 case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 1835 case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 1836 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1837 break; 1838 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1839 case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; 1840 case AttributeList::AT_transparent_union: 1841 HandleTransparentUnionAttr(D, Attr, S); 1842 break; 1843 case AttributeList::AT_objc_exception: 1844 HandleObjCExceptionAttr(D, Attr, S); 1845 break; 1846 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1847 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 1848 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1849 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1850 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1851 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1852 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1853 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 1854 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 1855 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1856 case AttributeList::IgnoredAttribute: 1857 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 1858 // Just ignore 1859 break; 1860 default: 1861 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1862 break; 1863 } 1864} 1865 1866/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1867/// attribute list to the specified decl, ignoring any type attributes. 1868void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 1869 while (AttrList) { 1870 ProcessDeclAttribute(S, D, *AttrList, *this); 1871 AttrList = AttrList->getNext(); 1872 } 1873} 1874 1875/// DeclClonePragmaWeak - clone existing decl (maybe definition), 1876/// #pragma weak needs a non-definition decl and source may not have one 1877NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 1878 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 1879 NamedDecl *NewD = 0; 1880 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 1881 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 1882 FD->getLocation(), DeclarationName(II), 1883 FD->getType(), FD->getDeclaratorInfo()); 1884 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 1885 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 1886 VD->getLocation(), II, 1887 VD->getType(), VD->getDeclaratorInfo(), 1888 VD->getStorageClass()); 1889 } 1890 return NewD; 1891} 1892 1893/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 1894/// applied to it, possibly with an alias. 1895void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 1896 if (W.getUsed()) return; // only do this once 1897 W.setUsed(true); 1898 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 1899 IdentifierInfo *NDId = ND->getIdentifier(); 1900 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 1901 NewD->addAttr(::new (Context) AliasAttr(NDId->getName())); 1902 NewD->addAttr(::new (Context) WeakAttr()); 1903 WeakTopLevelDecl.push_back(NewD); 1904 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 1905 // to insert Decl at TU scope, sorry. 1906 DeclContext *SavedContext = CurContext; 1907 CurContext = Context.getTranslationUnitDecl(); 1908 PushOnScopeChains(NewD, S); 1909 CurContext = SavedContext; 1910 } else { // just add weak to existing 1911 ND->addAttr(::new (Context) WeakAttr()); 1912 } 1913} 1914 1915/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 1916/// it, apply them to D. This is a bit tricky because PD can have attributes 1917/// specified in many different places, and we need to find and apply them all. 1918void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 1919 // Handle #pragma weak 1920 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 1921 if (ND->hasLinkage()) { 1922 WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 1923 if (W != WeakInfo()) { 1924 // Identifier referenced by #pragma weak before it was declared 1925 DeclApplyPragmaWeak(S, ND, W); 1926 WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 1927 } 1928 } 1929 } 1930 1931 // Apply decl attributes from the DeclSpec if present. 1932 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 1933 ProcessDeclAttributeList(S, D, Attrs); 1934 1935 // Walk the declarator structure, applying decl attributes that were in a type 1936 // position to the decl itself. This handles cases like: 1937 // int *__attr__(x)** D; 1938 // when X is a decl attribute. 1939 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 1940 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 1941 ProcessDeclAttributeList(S, D, Attrs); 1942 1943 // Finally, apply any attributes on the decl itself. 1944 if (const AttributeList *Attrs = PD.getAttributes()) 1945 ProcessDeclAttributeList(S, D, Attrs); 1946} 1947