SemaDeclAttr.cpp revision 1eb4433ac451dc16f4133a88af2d002ac26c58ef
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->getAsFunctionType(); 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->getAsObjCObjectPointerType(); 128 if (!PT) 129 return false; 130 131 const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType(); 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()->getAsFunctionType(); 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()->getAsFunctionType(); 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 = S.LookupName(S.TUScope, Attr.getParameterName(), 1108 Sema::LookupOrdinaryName); 1109 if (!CleanupDecl) { 1110 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1111 Attr.getParameterName(); 1112 return; 1113 } 1114 1115 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1116 if (!FD) { 1117 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1118 Attr.getParameterName(); 1119 return; 1120 } 1121 1122 if (FD->getNumParams() != 1) { 1123 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1124 Attr.getParameterName(); 1125 return; 1126 } 1127 1128 // We're currently more strict than GCC about what function types we accept. 1129 // If this ever proves to be a problem it should be easy to fix. 1130 QualType Ty = S.Context.getPointerType(VD->getType()); 1131 QualType ParamTy = FD->getParamDecl(0)->getType(); 1132 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1133 S.Diag(Attr.getLoc(), 1134 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1135 Attr.getParameterName() << ParamTy << Ty; 1136 return; 1137 } 1138 1139 d->addAttr(::new (S.Context) CleanupAttr(FD)); 1140} 1141 1142/// Handle __attribute__((format_arg((idx)))) attribute based on 1143/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1144static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1145 if (Attr.getNumArgs() != 1) { 1146 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1147 return; 1148 } 1149 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1150 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1151 << Attr.getName() << 0 /*function*/; 1152 return; 1153 } 1154 // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1155 // needed in order to be compatible with GCC the index must start with 1. 1156 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1157 unsigned FirstIdx = 1; 1158 // checks for the 2nd argument 1159 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1160 llvm::APSInt Idx(32); 1161 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1162 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1163 << "format" << 2 << IdxExpr->getSourceRange(); 1164 return; 1165 } 1166 1167 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1168 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1169 << "format" << 2 << IdxExpr->getSourceRange(); 1170 return; 1171 } 1172 1173 unsigned ArgIdx = Idx.getZExtValue() - 1; 1174 1175 // make sure the format string is really a string 1176 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1177 1178 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 1179 if (not_nsstring_type && 1180 !isCFStringType(Ty, S.Context) && 1181 (!Ty->isPointerType() || 1182 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1183 // FIXME: Should highlight the actual expression that has the wrong type. 1184 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1185 << (not_nsstring_type ? "a string type" : "an NSString") 1186 << IdxExpr->getSourceRange(); 1187 return; 1188 } 1189 Ty = getFunctionOrMethodResultType(d); 1190 if (!isNSStringType(Ty, S.Context) && 1191 !isCFStringType(Ty, S.Context) && 1192 (!Ty->isPointerType() || 1193 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1194 // FIXME: Should highlight the actual expression that has the wrong type. 1195 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1196 << (not_nsstring_type ? "string type" : "NSString") 1197 << IdxExpr->getSourceRange(); 1198 return; 1199 } 1200 1201 d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); 1202} 1203 1204/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1205/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1206static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1207 1208 if (!Attr.getParameterName()) { 1209 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1210 << "format" << 1; 1211 return; 1212 } 1213 1214 if (Attr.getNumArgs() != 2) { 1215 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1216 return; 1217 } 1218 1219 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1220 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1221 << Attr.getName() << 0 /*function*/; 1222 return; 1223 } 1224 1225 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1226 unsigned FirstIdx = 1; 1227 1228 const char *Format = Attr.getParameterName()->getName(); 1229 unsigned FormatLen = Attr.getParameterName()->getLength(); 1230 1231 // Normalize the argument, __foo__ becomes foo. 1232 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 1233 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 1234 Format += 2; 1235 FormatLen -= 4; 1236 } 1237 1238 bool Supported = false; 1239 bool is_NSString = false; 1240 bool is_strftime = false; 1241 bool is_CFString = false; 1242 1243 switch (FormatLen) { 1244 default: break; 1245 case 5: Supported = !memcmp(Format, "scanf", 5); break; 1246 case 6: Supported = !memcmp(Format, "printf", 6); break; 1247 case 7: Supported = !memcmp(Format, "printf0", 7) || 1248 !memcmp(Format, "strfmon", 7); break; 1249 case 8: 1250 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 1251 (is_NSString = !memcmp(Format, "NSString", 8)) || 1252 (is_CFString = !memcmp(Format, "CFString", 8)); 1253 break; 1254 } 1255 1256 if (!Supported) { 1257 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1258 << "format" << Attr.getParameterName()->getName(); 1259 return; 1260 } 1261 1262 // checks for the 2nd argument 1263 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1264 llvm::APSInt Idx(32); 1265 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1266 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1267 << "format" << 2 << IdxExpr->getSourceRange(); 1268 return; 1269 } 1270 1271 // FIXME: We should handle the implicit 'this' parameter in a more generic 1272 // way that can be used for other arguments. 1273 bool HasImplicitThisParam = false; 1274 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 1275 if (MD->isInstance()) { 1276 HasImplicitThisParam = true; 1277 NumArgs++; 1278 } 1279 } 1280 1281 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1282 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1283 << "format" << 2 << IdxExpr->getSourceRange(); 1284 return; 1285 } 1286 1287 // FIXME: Do we need to bounds check? 1288 unsigned ArgIdx = Idx.getZExtValue() - 1; 1289 1290 if (HasImplicitThisParam) ArgIdx--; 1291 1292 // make sure the format string is really a string 1293 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1294 1295 if (is_CFString) { 1296 if (!isCFStringType(Ty, S.Context)) { 1297 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1298 << "a CFString" << IdxExpr->getSourceRange(); 1299 return; 1300 } 1301 } else if (is_NSString) { 1302 // FIXME: do we need to check if the type is NSString*? What are the 1303 // semantics? 1304 if (!isNSStringType(Ty, S.Context)) { 1305 // FIXME: Should highlight the actual expression that has the wrong type. 1306 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1307 << "an NSString" << IdxExpr->getSourceRange(); 1308 return; 1309 } 1310 } else if (!Ty->isPointerType() || 1311 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1312 // FIXME: Should highlight the actual expression that has the wrong type. 1313 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1314 << "a string type" << IdxExpr->getSourceRange(); 1315 return; 1316 } 1317 1318 // check the 3rd argument 1319 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1320 llvm::APSInt FirstArg(32); 1321 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1322 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1323 << "format" << 3 << FirstArgExpr->getSourceRange(); 1324 return; 1325 } 1326 1327 // check if the function is variadic if the 3rd argument non-zero 1328 if (FirstArg != 0) { 1329 if (isFunctionOrMethodVariadic(d)) { 1330 ++NumArgs; // +1 for ... 1331 } else { 1332 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1333 return; 1334 } 1335 } 1336 1337 // strftime requires FirstArg to be 0 because it doesn't read from any 1338 // variable the input is just the current time + the format string. 1339 if (is_strftime) { 1340 if (FirstArg != 0) { 1341 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1342 << FirstArgExpr->getSourceRange(); 1343 return; 1344 } 1345 // if 0 it disables parameter checking (to use with e.g. va_list) 1346 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1347 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1348 << "format" << 3 << FirstArgExpr->getSourceRange(); 1349 return; 1350 } 1351 1352 d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen), 1353 Idx.getZExtValue(), FirstArg.getZExtValue())); 1354} 1355 1356static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1357 Sema &S) { 1358 // check the attribute arguments. 1359 if (Attr.getNumArgs() != 0) { 1360 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1361 return; 1362 } 1363 1364 // Try to find the underlying union declaration. 1365 RecordDecl *RD = 0; 1366 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1367 if (TD && TD->getUnderlyingType()->isUnionType()) 1368 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1369 else 1370 RD = dyn_cast<RecordDecl>(d); 1371 1372 if (!RD || !RD->isUnion()) { 1373 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1374 << Attr.getName() << 1 /*union*/; 1375 return; 1376 } 1377 1378 if (!RD->isDefinition()) { 1379 S.Diag(Attr.getLoc(), 1380 diag::warn_transparent_union_attribute_not_definition); 1381 return; 1382 } 1383 1384 RecordDecl::field_iterator Field = RD->field_begin(), 1385 FieldEnd = RD->field_end(); 1386 if (Field == FieldEnd) { 1387 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1388 return; 1389 } 1390 1391 FieldDecl *FirstField = *Field; 1392 QualType FirstType = FirstField->getType(); 1393 if (FirstType->isFloatingType() || FirstType->isVectorType()) { 1394 S.Diag(FirstField->getLocation(), 1395 diag::warn_transparent_union_attribute_floating); 1396 return; 1397 } 1398 1399 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1400 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1401 for (; Field != FieldEnd; ++Field) { 1402 QualType FieldType = Field->getType(); 1403 if (S.Context.getTypeSize(FieldType) != FirstSize || 1404 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1405 // Warn if we drop the attribute. 1406 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1407 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1408 : S.Context.getTypeAlign(FieldType); 1409 S.Diag(Field->getLocation(), 1410 diag::warn_transparent_union_attribute_field_size_align) 1411 << isSize << Field->getDeclName() << FieldBits; 1412 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1413 S.Diag(FirstField->getLocation(), 1414 diag::note_transparent_union_first_field_size_align) 1415 << isSize << FirstBits; 1416 return; 1417 } 1418 } 1419 1420 RD->addAttr(::new (S.Context) TransparentUnionAttr()); 1421} 1422 1423static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1424 // check the attribute arguments. 1425 if (Attr.getNumArgs() != 1) { 1426 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1427 return; 1428 } 1429 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1430 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1431 1432 // Make sure that there is a string literal as the annotation's single 1433 // argument. 1434 if (!SE) { 1435 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 1436 return; 1437 } 1438 d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), 1439 SE->getByteLength()))); 1440} 1441 1442static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1443 // check the attribute arguments. 1444 if (Attr.getNumArgs() > 1) { 1445 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1446 return; 1447 } 1448 1449 unsigned Align = 0; 1450 if (Attr.getNumArgs() == 0) { 1451 // FIXME: This should be the target specific maximum alignment. 1452 // (For now we just use 128 bits which is the maximum on X86). 1453 Align = 128; 1454 d->addAttr(::new (S.Context) AlignedAttr(Align)); 1455 return; 1456 } 1457 1458 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 1459 llvm::APSInt Alignment(32); 1460 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1461 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1462 << "aligned" << alignmentExpr->getSourceRange(); 1463 return; 1464 } 1465 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1466 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1467 << alignmentExpr->getSourceRange(); 1468 return; 1469 } 1470 1471 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 1472} 1473 1474/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1475/// type. 1476/// 1477/// Despite what would be logical, the mode attribute is a decl attribute, not a 1478/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1479/// HImode, not an intermediate pointer. 1480static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1481 // This attribute isn't documented, but glibc uses it. It changes 1482 // the width of an int or unsigned int to the specified size. 1483 1484 // Check that there aren't any arguments 1485 if (Attr.getNumArgs() != 0) { 1486 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1487 return; 1488 } 1489 1490 IdentifierInfo *Name = Attr.getParameterName(); 1491 if (!Name) { 1492 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1493 return; 1494 } 1495 const char *Str = Name->getName(); 1496 unsigned Len = Name->getLength(); 1497 1498 // Normalize the attribute name, __foo__ becomes foo. 1499 if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1500 Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1501 Str += 2; 1502 Len -= 4; 1503 } 1504 1505 unsigned DestWidth = 0; 1506 bool IntegerMode = true; 1507 bool ComplexMode = false; 1508 switch (Len) { 1509 case 2: 1510 switch (Str[0]) { 1511 case 'Q': DestWidth = 8; break; 1512 case 'H': DestWidth = 16; break; 1513 case 'S': DestWidth = 32; break; 1514 case 'D': DestWidth = 64; break; 1515 case 'X': DestWidth = 96; break; 1516 case 'T': DestWidth = 128; break; 1517 } 1518 if (Str[1] == 'F') { 1519 IntegerMode = false; 1520 } else if (Str[1] == 'C') { 1521 IntegerMode = false; 1522 ComplexMode = true; 1523 } else if (Str[1] != 'I') { 1524 DestWidth = 0; 1525 } 1526 break; 1527 case 4: 1528 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1529 // pointer on PIC16 and other embedded platforms. 1530 if (!memcmp(Str, "word", 4)) 1531 DestWidth = S.Context.Target.getPointerWidth(0); 1532 if (!memcmp(Str, "byte", 4)) 1533 DestWidth = S.Context.Target.getCharWidth(); 1534 break; 1535 case 7: 1536 if (!memcmp(Str, "pointer", 7)) 1537 DestWidth = S.Context.Target.getPointerWidth(0); 1538 break; 1539 } 1540 1541 QualType OldTy; 1542 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1543 OldTy = TD->getUnderlyingType(); 1544 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1545 OldTy = VD->getType(); 1546 else { 1547 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1548 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1549 return; 1550 } 1551 1552 if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType()) 1553 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1554 else if (IntegerMode) { 1555 if (!OldTy->isIntegralType()) 1556 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1557 } else if (ComplexMode) { 1558 if (!OldTy->isComplexType()) 1559 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1560 } else { 1561 if (!OldTy->isFloatingType()) 1562 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1563 } 1564 1565 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1566 // and friends, at least with glibc. 1567 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1568 // width on unusual platforms. 1569 // FIXME: Make sure floating-point mappings are accurate 1570 // FIXME: Support XF and TF types 1571 QualType NewTy; 1572 switch (DestWidth) { 1573 case 0: 1574 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1575 return; 1576 default: 1577 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1578 return; 1579 case 8: 1580 if (!IntegerMode) { 1581 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1582 return; 1583 } 1584 if (OldTy->isSignedIntegerType()) 1585 NewTy = S.Context.SignedCharTy; 1586 else 1587 NewTy = S.Context.UnsignedCharTy; 1588 break; 1589 case 16: 1590 if (!IntegerMode) { 1591 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1592 return; 1593 } 1594 if (OldTy->isSignedIntegerType()) 1595 NewTy = S.Context.ShortTy; 1596 else 1597 NewTy = S.Context.UnsignedShortTy; 1598 break; 1599 case 32: 1600 if (!IntegerMode) 1601 NewTy = S.Context.FloatTy; 1602 else if (OldTy->isSignedIntegerType()) 1603 NewTy = S.Context.IntTy; 1604 else 1605 NewTy = S.Context.UnsignedIntTy; 1606 break; 1607 case 64: 1608 if (!IntegerMode) 1609 NewTy = S.Context.DoubleTy; 1610 else if (OldTy->isSignedIntegerType()) 1611 NewTy = S.Context.LongLongTy; 1612 else 1613 NewTy = S.Context.UnsignedLongLongTy; 1614 break; 1615 case 96: 1616 NewTy = S.Context.LongDoubleTy; 1617 break; 1618 case 128: 1619 if (!IntegerMode) { 1620 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1621 return; 1622 } 1623 NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 1624 break; 1625 } 1626 1627 if (ComplexMode) { 1628 NewTy = S.Context.getComplexType(NewTy); 1629 } 1630 1631 // Install the new type. 1632 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1633 TD->setUnderlyingType(NewTy); 1634 else 1635 cast<ValueDecl>(D)->setType(NewTy); 1636} 1637 1638static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1639 // check the attribute arguments. 1640 if (Attr.getNumArgs() > 0) { 1641 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1642 return; 1643 } 1644 1645 if (!isFunctionOrMethod(d)) { 1646 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1647 << Attr.getName() << 0 /*function*/; 1648 return; 1649 } 1650 1651 d->addAttr(::new (S.Context) NoDebugAttr()); 1652} 1653 1654static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1655 // check the attribute arguments. 1656 if (Attr.getNumArgs() != 0) { 1657 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1658 return; 1659 } 1660 1661 if (!isa<FunctionDecl>(d)) { 1662 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1663 << Attr.getName() << 0 /*function*/; 1664 return; 1665 } 1666 1667 d->addAttr(::new (S.Context) NoInlineAttr()); 1668} 1669 1670static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1671 // check the attribute arguments. 1672 if (Attr.getNumArgs() != 0) { 1673 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1674 return; 1675 } 1676 1677 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1678 if (Fn == 0) { 1679 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1680 << Attr.getName() << 0 /*function*/; 1681 return; 1682 } 1683 1684 if (!Fn->isInline()) { 1685 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1686 return; 1687 } 1688 1689 d->addAttr(::new (S.Context) GNUInlineAttr()); 1690} 1691 1692static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1693 // check the attribute arguments. 1694 if (Attr.getNumArgs() != 1) { 1695 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1696 return; 1697 } 1698 1699 if (!isFunctionOrMethod(d)) { 1700 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1701 << Attr.getName() << 0 /*function*/; 1702 return; 1703 } 1704 1705 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 1706 llvm::APSInt NumParams(32); 1707 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 1708 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1709 << "regparm" << NumParamsExpr->getSourceRange(); 1710 return; 1711 } 1712 1713 if (S.Context.Target.getRegParmMax() == 0) { 1714 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 1715 << NumParamsExpr->getSourceRange(); 1716 return; 1717 } 1718 1719 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1720 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1721 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 1722 return; 1723 } 1724 1725 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1726} 1727 1728//===----------------------------------------------------------------------===// 1729// Checker-specific attribute handlers. 1730//===----------------------------------------------------------------------===// 1731 1732static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1733 Sema &S) { 1734 1735 QualType RetTy; 1736 1737 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 1738 RetTy = MD->getResultType(); 1739 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 1740 RetTy = FD->getResultType(); 1741 else { 1742 SourceLocation L = Attr.getLoc(); 1743 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 1744 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 1745 return; 1746 } 1747 1748 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 1749 || RetTy->getAsObjCObjectPointerType())) { 1750 SourceLocation L = Attr.getLoc(); 1751 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 1752 << SourceRange(L, L) << Attr.getName(); 1753 return; 1754 } 1755 1756 switch (Attr.getKind()) { 1757 default: 1758 assert(0 && "invalid ownership attribute"); 1759 return; 1760 case AttributeList::AT_cf_returns_retained: 1761 d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1762 return; 1763 case AttributeList::AT_ns_returns_retained: 1764 d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1765 return; 1766 }; 1767} 1768 1769//===----------------------------------------------------------------------===// 1770// Top Level Sema Entry Points 1771//===----------------------------------------------------------------------===// 1772 1773/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1774/// the attribute applies to decls. If the attribute is a type attribute, just 1775/// silently ignore it. 1776static void ProcessDeclAttribute(Scope *scope, Decl *D, 1777 const AttributeList &Attr, Sema &S) { 1778 if (Attr.isDeclspecAttribute()) 1779 // FIXME: Try to deal with __declspec attributes! 1780 return; 1781 switch (Attr.getKind()) { 1782 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1783 case AttributeList::AT_address_space: 1784 case AttributeList::AT_objc_gc: 1785 // Ignore these, these are type attributes, handled by 1786 // ProcessTypeAttributes. 1787 break; 1788 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 1789 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1790 case AttributeList::AT_always_inline: 1791 HandleAlwaysInlineAttr (D, Attr, S); break; 1792 case AttributeList::AT_analyzer_noreturn: 1793 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 1794 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 1795 case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1796 case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 1797 case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1798 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 1799 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 1800 case AttributeList::AT_ext_vector_type: 1801 HandleExtVectorTypeAttr(scope, D, Attr, S); 1802 break; 1803 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1804 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1805 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 1806 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(D, Attr, S); break; 1807 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1808 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 1809 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 1810 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 1811 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1812 1813 // Checker-specific. 1814 case AttributeList::AT_ns_returns_retained: 1815 case AttributeList::AT_cf_returns_retained: 1816 HandleNSReturnsRetainedAttr(D, Attr, S); break; 1817 1818 case AttributeList::AT_reqd_wg_size: 1819 HandleReqdWorkGroupSize(D, Attr, S); break; 1820 1821 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 1822 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 1823 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1824 case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 1825 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1826 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 1827 case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 1828 case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 1829 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1830 break; 1831 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1832 case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; 1833 case AttributeList::AT_transparent_union: 1834 HandleTransparentUnionAttr(D, Attr, S); 1835 break; 1836 case AttributeList::AT_objc_exception: 1837 HandleObjCExceptionAttr(D, Attr, S); 1838 break; 1839 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1840 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 1841 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1842 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1843 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1844 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1845 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1846 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 1847 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 1848 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1849 case AttributeList::IgnoredAttribute: 1850 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 1851 // Just ignore 1852 break; 1853 default: 1854 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1855 break; 1856 } 1857} 1858 1859/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1860/// attribute list to the specified decl, ignoring any type attributes. 1861void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 1862 while (AttrList) { 1863 ProcessDeclAttribute(S, D, *AttrList, *this); 1864 AttrList = AttrList->getNext(); 1865 } 1866} 1867 1868/// DeclClonePragmaWeak - clone existing decl (maybe definition), 1869/// #pragma weak needs a non-definition decl and source may not have one 1870NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 1871 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 1872 NamedDecl *NewD = 0; 1873 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 1874 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 1875 FD->getLocation(), DeclarationName(II), 1876 FD->getType(), FD->getDeclaratorInfo()); 1877 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 1878 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 1879 VD->getLocation(), II, 1880 VD->getType(), VD->getDeclaratorInfo(), 1881 VD->getStorageClass()); 1882 } 1883 return NewD; 1884} 1885 1886/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 1887/// applied to it, possibly with an alias. 1888void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 1889 if (W.getUsed()) return; // only do this once 1890 W.setUsed(true); 1891 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 1892 IdentifierInfo *NDId = ND->getIdentifier(); 1893 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 1894 NewD->addAttr(::new (Context) AliasAttr(NDId->getName())); 1895 NewD->addAttr(::new (Context) WeakAttr()); 1896 WeakTopLevelDecl.push_back(NewD); 1897 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 1898 // to insert Decl at TU scope, sorry. 1899 DeclContext *SavedContext = CurContext; 1900 CurContext = Context.getTranslationUnitDecl(); 1901 PushOnScopeChains(NewD, S); 1902 CurContext = SavedContext; 1903 } else { // just add weak to existing 1904 ND->addAttr(::new (Context) WeakAttr()); 1905 } 1906} 1907 1908/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 1909/// it, apply them to D. This is a bit tricky because PD can have attributes 1910/// specified in many different places, and we need to find and apply them all. 1911void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 1912 // Handle #pragma weak 1913 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 1914 if (ND->hasLinkage()) { 1915 WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 1916 if (W != WeakInfo()) { 1917 // Identifier referenced by #pragma weak before it was declared 1918 DeclApplyPragmaWeak(S, ND, W); 1919 WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 1920 } 1921 } 1922 } 1923 1924 // Apply decl attributes from the DeclSpec if present. 1925 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 1926 ProcessDeclAttributeList(S, D, Attrs); 1927 1928 // Walk the declarator structure, applying decl attributes that were in a type 1929 // position to the decl itself. This handles cases like: 1930 // int *__attr__(x)** D; 1931 // when X is a decl attribute. 1932 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 1933 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 1934 ProcessDeclAttributeList(S, D, Attrs); 1935 1936 // Finally, apply any attributes on the decl itself. 1937 if (const AttributeList *Attrs = PD.getAttributes()) 1938 ProcessDeclAttributeList(S, D, Attrs); 1939} 1940