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