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