SemaDeclAttr.cpp revision f857798fa77ac50c6d0a262d96ad6176187190e3
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/// isFunction - 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 CXXScopeSpec SS; 181 UnqualifiedId id; 182 id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 183 sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); 184 } else { 185 // check the attribute arguments. 186 if (Attr.getNumArgs() != 1) { 187 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 188 return; 189 } 190 sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 191 } 192 193 // Instantiate/Install the vector type, and let Sema build the type for us. 194 // This will run the reguired checks. 195 QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc()); 196 if (!T.isNull()) { 197 // FIXME: preserve the old source info. 198 tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 199 200 // Remember this typedef decl, we will need it later for diagnostics. 201 S.ExtVectorDecls.push_back(tDecl); 202 } 203} 204 205static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 206 // check the attribute arguments. 207 if (Attr.getNumArgs() > 0) { 208 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 209 return; 210 } 211 212 if (TagDecl *TD = dyn_cast<TagDecl>(d)) 213 TD->addAttr(::new (S.Context) PackedAttr); 214 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 215 // If the alignment is less than or equal to 8 bits, the packed attribute 216 // has no effect. 217 if (!FD->getType()->isIncompleteType() && 218 S.Context.getTypeAlign(FD->getType()) <= 8) 219 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 220 << Attr.getName() << FD->getType(); 221 else 222 FD->addAttr(::new (S.Context) PackedAttr); 223 } else 224 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 225} 226 227static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 228 // check the attribute arguments. 229 if (Attr.getNumArgs() > 0) { 230 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 231 return; 232 } 233 234 // The IBOutlet attribute only applies to instance variables of Objective-C 235 // classes. 236 if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) 237 d->addAttr(::new (S.Context) IBOutletAttr()); 238 else 239 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet); 240} 241 242static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 243 // GCC ignores the nonnull attribute on K&R style function prototypes, so we 244 // ignore it as well 245 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 246 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 247 << Attr.getName() << 0 /*function*/; 248 return; 249 } 250 251 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 252 253 // The nonnull attribute only applies to pointers. 254 llvm::SmallVector<unsigned, 10> NonNullArgs; 255 256 for (AttributeList::arg_iterator I=Attr.arg_begin(), 257 E=Attr.arg_end(); I!=E; ++I) { 258 259 260 // The argument must be an integer constant expression. 261 Expr *Ex = static_cast<Expr *>(*I); 262 llvm::APSInt ArgNum(32); 263 if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 264 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 265 << "nonnull" << Ex->getSourceRange(); 266 return; 267 } 268 269 unsigned x = (unsigned) ArgNum.getZExtValue(); 270 271 if (x < 1 || x > NumArgs) { 272 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 273 << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 274 return; 275 } 276 277 --x; 278 279 // Is the function argument a pointer type? 280 QualType T = getFunctionOrMethodArgType(d, x); 281 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 282 // FIXME: Should also highlight argument in decl. 283 S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 284 << "nonnull" << Ex->getSourceRange(); 285 continue; 286 } 287 288 NonNullArgs.push_back(x); 289 } 290 291 // If no arguments were specified to __attribute__((nonnull)) then all pointer 292 // arguments have a nonnull attribute. 293 if (NonNullArgs.empty()) { 294 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 295 QualType T = getFunctionOrMethodArgType(d, I); 296 if (T->isAnyPointerType() || T->isBlockPointerType()) 297 NonNullArgs.push_back(I); 298 } 299 300 if (NonNullArgs.empty()) { 301 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 302 return; 303 } 304 } 305 306 unsigned* start = &NonNullArgs[0]; 307 unsigned size = NonNullArgs.size(); 308 std::sort(start, start + size); 309 d->addAttr(::new (S.Context) NonNullAttr(start, size)); 310} 311 312static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 313 // check the attribute arguments. 314 if (Attr.getNumArgs() != 1) { 315 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 316 return; 317 } 318 319 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 320 Arg = Arg->IgnoreParenCasts(); 321 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 322 323 if (Str == 0 || Str->isWide()) { 324 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 325 << "alias" << 1; 326 return; 327 } 328 329 // FIXME: check if target symbol exists in current file 330 331 d->addAttr(::new (S.Context) AliasAttr(Str->getString())); 332} 333 334static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 335 Sema &S) { 336 // check the attribute arguments. 337 if (Attr.getNumArgs() != 0) { 338 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 339 return; 340 } 341 342 if (!isa<FunctionDecl>(d)) { 343 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 344 << Attr.getName() << 0 /*function*/; 345 return; 346 } 347 348 d->addAttr(::new (S.Context) AlwaysInlineAttr()); 349} 350 351static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 352 // check the attribute arguments. 353 if (Attr.getNumArgs() != 0) { 354 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 355 return; 356 } 357 358 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 359 QualType RetTy = FD->getResultType(); 360 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 361 d->addAttr(::new (S.Context) MallocAttr()); 362 return; 363 } 364 } 365 366 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 367} 368 369static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 370 Sema &S) { 371 // check the attribute arguments. 372 if (Attr.getNumArgs() != 0) { 373 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 374 return false; 375 } 376 377 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 378 ValueDecl *VD = dyn_cast<ValueDecl>(d); 379 if (VD == 0 || (!VD->getType()->isBlockPointerType() 380 && !VD->getType()->isFunctionPointerType())) { 381 S.Diag(Attr.getLoc(), 382 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 383 : diag::warn_attribute_wrong_decl_type) 384 << Attr.getName() << 0 /*function*/; 385 return false; 386 } 387 } 388 389 return true; 390} 391 392static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 393 if (HandleCommonNoReturnAttr(d, Attr, S)) 394 d->addAttr(::new (S.Context) NoReturnAttr()); 395} 396 397static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 398 Sema &S) { 399 if (HandleCommonNoReturnAttr(d, Attr, S)) 400 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 401} 402 403static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 404 if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 405 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 406 << Attr.getName() << 8; /*function, method, or parameter*/ 407 return; 408 } 409 // FIXME: Actually store the attribute on the declaration 410} 411 412static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 413 // check the attribute arguments. 414 if (Attr.getNumArgs() != 0) { 415 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 416 return; 417 } 418 419 if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 420 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 421 << Attr.getName() << 2 /*variable and function*/; 422 return; 423 } 424 425 d->addAttr(::new (S.Context) UnusedAttr()); 426} 427 428static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 429 // check the attribute arguments. 430 if (Attr.getNumArgs() != 0) { 431 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 432 return; 433 } 434 435 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 436 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 437 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 438 return; 439 } 440 } else if (!isFunctionOrMethod(d)) { 441 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 442 << Attr.getName() << 2 /*variable and function*/; 443 return; 444 } 445 446 d->addAttr(::new (S.Context) UsedAttr()); 447} 448 449static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 450 // check the attribute arguments. 451 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 452 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 453 << "0 or 1"; 454 return; 455 } 456 457 int priority = 65535; // FIXME: Do not hardcode such constants. 458 if (Attr.getNumArgs() > 0) { 459 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 460 llvm::APSInt Idx(32); 461 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 462 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 463 << "constructor" << 1 << E->getSourceRange(); 464 return; 465 } 466 priority = Idx.getZExtValue(); 467 } 468 469 if (!isa<FunctionDecl>(d)) { 470 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 471 << Attr.getName() << 0 /*function*/; 472 return; 473 } 474 475 d->addAttr(::new (S.Context) ConstructorAttr(priority)); 476} 477 478static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 479 // check the attribute arguments. 480 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 481 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 482 << "0 or 1"; 483 return; 484 } 485 486 int priority = 65535; // FIXME: Do not hardcode such constants. 487 if (Attr.getNumArgs() > 0) { 488 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 489 llvm::APSInt Idx(32); 490 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 491 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 492 << "destructor" << 1 << E->getSourceRange(); 493 return; 494 } 495 priority = Idx.getZExtValue(); 496 } 497 498 if (!isa<FunctionDecl>(d)) { 499 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 500 << Attr.getName() << 0 /*function*/; 501 return; 502 } 503 504 d->addAttr(::new (S.Context) DestructorAttr(priority)); 505} 506 507static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 508 // check the attribute arguments. 509 if (Attr.getNumArgs() != 0) { 510 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 511 return; 512 } 513 514 d->addAttr(::new (S.Context) DeprecatedAttr()); 515} 516 517static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 518 // check the attribute arguments. 519 if (Attr.getNumArgs() != 0) { 520 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 521 return; 522 } 523 524 d->addAttr(::new (S.Context) UnavailableAttr()); 525} 526 527static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 528 // check the attribute arguments. 529 if (Attr.getNumArgs() != 1) { 530 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 531 return; 532 } 533 534 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 535 Arg = Arg->IgnoreParenCasts(); 536 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 537 538 if (Str == 0 || Str->isWide()) { 539 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 540 << "visibility" << 1; 541 return; 542 } 543 544 const char *TypeStr = Str->getStrData(); 545 unsigned TypeLen = Str->getByteLength(); 546 VisibilityAttr::VisibilityTypes type; 547 548 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 549 type = VisibilityAttr::DefaultVisibility; 550 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 551 type = VisibilityAttr::HiddenVisibility; 552 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 553 type = VisibilityAttr::HiddenVisibility; // FIXME 554 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 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 D->addAttr(::new (S.Context) SectionAttr(SE->getString())); 930 return; 931 } 932 933 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 934 << Error; 935 936} 937 938static void HandleCDeclAttr(Decl *d, const AttributeList &Attr, Sema &S) { 939 // Attribute has no arguments. 940 if (Attr.getNumArgs() != 0) { 941 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 942 return; 943 } 944 945 // Attribute can be applied only to functions. 946 if (!isa<FunctionDecl>(d)) { 947 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 948 << Attr.getName() << 0 /*function*/; 949 return; 950 } 951 952 // cdecl and fastcall attributes are mutually incompatible. 953 if (d->getAttr<FastCallAttr>()) { 954 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 955 << "cdecl" << "fastcall"; 956 return; 957 } 958 959 // cdecl and stdcall attributes are mutually incompatible. 960 if (d->getAttr<StdCallAttr>()) { 961 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 962 << "cdecl" << "stdcall"; 963 return; 964 } 965 966 d->addAttr(::new (S.Context) CDeclAttr()); 967} 968 969 970static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 971 // Attribute has no arguments. 972 if (Attr.getNumArgs() != 0) { 973 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 974 return; 975 } 976 977 // Attribute can be applied only to functions. 978 if (!isa<FunctionDecl>(d)) { 979 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 980 << Attr.getName() << 0 /*function*/; 981 return; 982 } 983 984 // stdcall and fastcall attributes are mutually incompatible. 985 if (d->getAttr<FastCallAttr>()) { 986 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 987 << "stdcall" << "fastcall"; 988 return; 989 } 990 991 d->addAttr(::new (S.Context) StdCallAttr()); 992} 993 994/// Diagnose the use of a non-standard calling convention on the given 995/// function. 996static void DiagnoseCConv(FunctionDecl *D, const char *CConv, 997 SourceLocation Loc, Sema &S) { 998 if (!D->hasPrototype()) { 999 S.Diag(Loc, diag::err_cconv_knr) << CConv; 1000 return; 1001 } 1002 1003 const FunctionProtoType *T = D->getType()->getAs<FunctionProtoType>(); 1004 if (T->isVariadic()) { 1005 S.Diag(Loc, diag::err_cconv_varargs) << CConv; 1006 return; 1007 } 1008} 1009 1010static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1011 // Attribute has no arguments. 1012 if (Attr.getNumArgs() != 0) { 1013 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1014 return; 1015 } 1016 1017 if (!isa<FunctionDecl>(d)) { 1018 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1019 << Attr.getName() << 0 /*function*/; 1020 return; 1021 } 1022 1023 DiagnoseCConv(cast<FunctionDecl>(d), "fastcall", Attr.getLoc(), S); 1024 1025 // stdcall and fastcall attributes are mutually incompatible. 1026 if (d->getAttr<StdCallAttr>()) { 1027 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1028 << "fastcall" << "stdcall"; 1029 return; 1030 } 1031 1032 d->addAttr(::new (S.Context) FastCallAttr()); 1033} 1034 1035static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1036 // check the attribute arguments. 1037 if (Attr.getNumArgs() != 0) { 1038 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1039 return; 1040 } 1041 1042 d->addAttr(::new (S.Context) NoThrowAttr()); 1043} 1044 1045static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1046 // check the attribute arguments. 1047 if (Attr.getNumArgs() != 0) { 1048 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1049 return; 1050 } 1051 1052 d->addAttr(::new (S.Context) ConstAttr()); 1053} 1054 1055static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1056 // check the attribute arguments. 1057 if (Attr.getNumArgs() != 0) { 1058 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1059 return; 1060 } 1061 1062 d->addAttr(::new (S.Context) PureAttr()); 1063} 1064 1065static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1066 if (!Attr.getParameterName()) { 1067 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1068 return; 1069 } 1070 1071 if (Attr.getNumArgs() != 0) { 1072 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1073 return; 1074 } 1075 1076 VarDecl *VD = dyn_cast<VarDecl>(d); 1077 1078 if (!VD || !VD->hasLocalStorage()) { 1079 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1080 return; 1081 } 1082 1083 // Look up the function 1084 NamedDecl *CleanupDecl 1085 = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 1086 Sema::LookupOrdinaryName); 1087 if (!CleanupDecl) { 1088 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1089 Attr.getParameterName(); 1090 return; 1091 } 1092 1093 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1094 if (!FD) { 1095 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1096 Attr.getParameterName(); 1097 return; 1098 } 1099 1100 if (FD->getNumParams() != 1) { 1101 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1102 Attr.getParameterName(); 1103 return; 1104 } 1105 1106 // We're currently more strict than GCC about what function types we accept. 1107 // If this ever proves to be a problem it should be easy to fix. 1108 QualType Ty = S.Context.getPointerType(VD->getType()); 1109 QualType ParamTy = FD->getParamDecl(0)->getType(); 1110 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1111 S.Diag(Attr.getLoc(), 1112 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1113 Attr.getParameterName() << ParamTy << Ty; 1114 return; 1115 } 1116 1117 d->addAttr(::new (S.Context) CleanupAttr(FD)); 1118} 1119 1120/// Handle __attribute__((format_arg((idx)))) attribute based on 1121/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1122static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1123 if (Attr.getNumArgs() != 1) { 1124 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1125 return; 1126 } 1127 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1128 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1129 << Attr.getName() << 0 /*function*/; 1130 return; 1131 } 1132 // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1133 // needed in order to be compatible with GCC the index must start with 1. 1134 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1135 unsigned FirstIdx = 1; 1136 // checks for the 2nd argument 1137 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1138 llvm::APSInt Idx(32); 1139 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1140 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1141 << "format" << 2 << IdxExpr->getSourceRange(); 1142 return; 1143 } 1144 1145 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1146 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1147 << "format" << 2 << IdxExpr->getSourceRange(); 1148 return; 1149 } 1150 1151 unsigned ArgIdx = Idx.getZExtValue() - 1; 1152 1153 // make sure the format string is really a string 1154 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1155 1156 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 1157 if (not_nsstring_type && 1158 !isCFStringType(Ty, S.Context) && 1159 (!Ty->isPointerType() || 1160 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1161 // FIXME: Should highlight the actual expression that has the wrong type. 1162 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1163 << (not_nsstring_type ? "a string type" : "an NSString") 1164 << IdxExpr->getSourceRange(); 1165 return; 1166 } 1167 Ty = getFunctionOrMethodResultType(d); 1168 if (!isNSStringType(Ty, S.Context) && 1169 !isCFStringType(Ty, S.Context) && 1170 (!Ty->isPointerType() || 1171 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1172 // FIXME: Should highlight the actual expression that has the wrong type. 1173 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1174 << (not_nsstring_type ? "string type" : "NSString") 1175 << IdxExpr->getSourceRange(); 1176 return; 1177 } 1178 1179 d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); 1180} 1181 1182enum FormatAttrKind { 1183 CFStringFormat, 1184 NSStringFormat, 1185 StrftimeFormat, 1186 SupportedFormat, 1187 InvalidFormat 1188}; 1189 1190/// getFormatAttrKind - Map from format attribute names to supported format 1191/// types. 1192static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 1193 // Check for formats that get handled specially. 1194 if (Format == "NSString") 1195 return NSStringFormat; 1196 if (Format == "CFString") 1197 return CFStringFormat; 1198 if (Format == "strftime") 1199 return StrftimeFormat; 1200 1201 // Otherwise, check for supported formats. 1202 if (Format == "scanf" || Format == "printf" || Format == "printf0" || 1203 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 1204 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 1205 Format == "zcmn_err") 1206 return SupportedFormat; 1207 1208 return InvalidFormat; 1209} 1210 1211/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1212/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1213static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1214 1215 if (!Attr.getParameterName()) { 1216 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1217 << "format" << 1; 1218 return; 1219 } 1220 1221 if (Attr.getNumArgs() != 2) { 1222 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1223 return; 1224 } 1225 1226 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1227 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1228 << Attr.getName() << 0 /*function*/; 1229 return; 1230 } 1231 1232 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1233 unsigned FirstIdx = 1; 1234 1235 llvm::StringRef Format = Attr.getParameterName()->getName(); 1236 1237 // Normalize the argument, __foo__ becomes foo. 1238 if (Format.startswith("__") && Format.endswith("__")) 1239 Format = Format.substr(2, Format.size() - 4); 1240 1241 // Check for supported formats. 1242 FormatAttrKind Kind = getFormatAttrKind(Format); 1243 if (Kind == InvalidFormat) { 1244 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1245 << "format" << Attr.getParameterName()->getName(); 1246 return; 1247 } 1248 1249 // checks for the 2nd argument 1250 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1251 llvm::APSInt Idx(32); 1252 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1253 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1254 << "format" << 2 << IdxExpr->getSourceRange(); 1255 return; 1256 } 1257 1258 // FIXME: We should handle the implicit 'this' parameter in a more generic 1259 // way that can be used for other arguments. 1260 bool HasImplicitThisParam = false; 1261 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 1262 if (MD->isInstance()) { 1263 HasImplicitThisParam = true; 1264 NumArgs++; 1265 } 1266 } 1267 1268 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1269 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1270 << "format" << 2 << IdxExpr->getSourceRange(); 1271 return; 1272 } 1273 1274 // FIXME: Do we need to bounds check? 1275 unsigned ArgIdx = Idx.getZExtValue() - 1; 1276 1277 if (HasImplicitThisParam) { 1278 if (ArgIdx == 0) { 1279 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1280 << "a string type" << IdxExpr->getSourceRange(); 1281 return; 1282 } 1283 ArgIdx--; 1284 } 1285 1286 // make sure the format string is really a string 1287 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1288 1289 if (Kind == CFStringFormat) { 1290 if (!isCFStringType(Ty, S.Context)) { 1291 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1292 << "a CFString" << IdxExpr->getSourceRange(); 1293 return; 1294 } 1295 } else if (Kind == NSStringFormat) { 1296 // FIXME: do we need to check if the type is NSString*? What are the 1297 // semantics? 1298 if (!isNSStringType(Ty, S.Context)) { 1299 // FIXME: Should highlight the actual expression that has the wrong type. 1300 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1301 << "an NSString" << IdxExpr->getSourceRange(); 1302 return; 1303 } 1304 } else if (!Ty->isPointerType() || 1305 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1306 // FIXME: Should highlight the actual expression that has the wrong type. 1307 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1308 << "a string type" << IdxExpr->getSourceRange(); 1309 return; 1310 } 1311 1312 // check the 3rd argument 1313 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1314 llvm::APSInt FirstArg(32); 1315 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1316 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1317 << "format" << 3 << FirstArgExpr->getSourceRange(); 1318 return; 1319 } 1320 1321 // check if the function is variadic if the 3rd argument non-zero 1322 if (FirstArg != 0) { 1323 if (isFunctionOrMethodVariadic(d)) { 1324 ++NumArgs; // +1 for ... 1325 } else { 1326 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1327 return; 1328 } 1329 } 1330 1331 // strftime requires FirstArg to be 0 because it doesn't read from any 1332 // variable the input is just the current time + the format string. 1333 if (Kind == StrftimeFormat) { 1334 if (FirstArg != 0) { 1335 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1336 << FirstArgExpr->getSourceRange(); 1337 return; 1338 } 1339 // if 0 it disables parameter checking (to use with e.g. va_list) 1340 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1341 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1342 << "format" << 3 << FirstArgExpr->getSourceRange(); 1343 return; 1344 } 1345 1346 d->addAttr(::new (S.Context) FormatAttr(Format, Idx.getZExtValue(), 1347 FirstArg.getZExtValue())); 1348} 1349 1350static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1351 Sema &S) { 1352 // check the attribute arguments. 1353 if (Attr.getNumArgs() != 0) { 1354 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1355 return; 1356 } 1357 1358 // Try to find the underlying union declaration. 1359 RecordDecl *RD = 0; 1360 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1361 if (TD && TD->getUnderlyingType()->isUnionType()) 1362 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1363 else 1364 RD = dyn_cast<RecordDecl>(d); 1365 1366 if (!RD || !RD->isUnion()) { 1367 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1368 << Attr.getName() << 1 /*union*/; 1369 return; 1370 } 1371 1372 if (!RD->isDefinition()) { 1373 S.Diag(Attr.getLoc(), 1374 diag::warn_transparent_union_attribute_not_definition); 1375 return; 1376 } 1377 1378 RecordDecl::field_iterator Field = RD->field_begin(), 1379 FieldEnd = RD->field_end(); 1380 if (Field == FieldEnd) { 1381 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1382 return; 1383 } 1384 1385 FieldDecl *FirstField = *Field; 1386 QualType FirstType = FirstField->getType(); 1387 if (FirstType->isFloatingType() || FirstType->isVectorType()) { 1388 S.Diag(FirstField->getLocation(), 1389 diag::warn_transparent_union_attribute_floating); 1390 return; 1391 } 1392 1393 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1394 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1395 for (; Field != FieldEnd; ++Field) { 1396 QualType FieldType = Field->getType(); 1397 if (S.Context.getTypeSize(FieldType) != FirstSize || 1398 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1399 // Warn if we drop the attribute. 1400 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1401 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1402 : S.Context.getTypeAlign(FieldType); 1403 S.Diag(Field->getLocation(), 1404 diag::warn_transparent_union_attribute_field_size_align) 1405 << isSize << Field->getDeclName() << FieldBits; 1406 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1407 S.Diag(FirstField->getLocation(), 1408 diag::note_transparent_union_first_field_size_align) 1409 << isSize << FirstBits; 1410 return; 1411 } 1412 } 1413 1414 RD->addAttr(::new (S.Context) TransparentUnionAttr()); 1415} 1416 1417static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1418 // check the attribute arguments. 1419 if (Attr.getNumArgs() != 1) { 1420 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1421 return; 1422 } 1423 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1424 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1425 1426 // Make sure that there is a string literal as the annotation's single 1427 // argument. 1428 if (!SE) { 1429 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 1430 return; 1431 } 1432 d->addAttr(::new (S.Context) AnnotateAttr(SE->getString())); 1433} 1434 1435static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1436 // check the attribute arguments. 1437 if (Attr.getNumArgs() > 1) { 1438 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1439 return; 1440 } 1441 1442 //FIXME: The C++0x version of this attribute has more limited applicabilty 1443 // than GNU's, and should error out when it is used to specify a 1444 // weaker alignment, rather than being silently ignored. 1445 1446 unsigned Align = 0; 1447 if (Attr.getNumArgs() == 0) { 1448 // FIXME: This should be the target specific maximum alignment. 1449 // (For now we just use 128 bits which is the maximum on X86). 1450 Align = 128; 1451 d->addAttr(::new (S.Context) AlignedAttr(Align)); 1452 return; 1453 } 1454 1455 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 1456 llvm::APSInt Alignment(32); 1457 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1458 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1459 << "aligned" << alignmentExpr->getSourceRange(); 1460 return; 1461 } 1462 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1463 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1464 << alignmentExpr->getSourceRange(); 1465 return; 1466 } 1467 1468 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 1469} 1470 1471/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1472/// type. 1473/// 1474/// Despite what would be logical, the mode attribute is a decl attribute, not a 1475/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1476/// HImode, not an intermediate pointer. 1477static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1478 // This attribute isn't documented, but glibc uses it. It changes 1479 // the width of an int or unsigned int to the specified size. 1480 1481 // Check that there aren't any arguments 1482 if (Attr.getNumArgs() != 0) { 1483 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1484 return; 1485 } 1486 1487 IdentifierInfo *Name = Attr.getParameterName(); 1488 if (!Name) { 1489 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1490 return; 1491 } 1492 1493 llvm::StringRef Str = Attr.getParameterName()->getName(); 1494 1495 // Normalize the attribute name, __foo__ becomes foo. 1496 if (Str.startswith("__") && Str.endswith("__")) 1497 Str = Str.substr(2, Str.size() - 4); 1498 1499 unsigned DestWidth = 0; 1500 bool IntegerMode = true; 1501 bool ComplexMode = false; 1502 switch (Str.size()) { 1503 case 2: 1504 switch (Str[0]) { 1505 case 'Q': DestWidth = 8; break; 1506 case 'H': DestWidth = 16; break; 1507 case 'S': DestWidth = 32; break; 1508 case 'D': DestWidth = 64; break; 1509 case 'X': DestWidth = 96; break; 1510 case 'T': DestWidth = 128; break; 1511 } 1512 if (Str[1] == 'F') { 1513 IntegerMode = false; 1514 } else if (Str[1] == 'C') { 1515 IntegerMode = false; 1516 ComplexMode = true; 1517 } else if (Str[1] != 'I') { 1518 DestWidth = 0; 1519 } 1520 break; 1521 case 4: 1522 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1523 // pointer on PIC16 and other embedded platforms. 1524 if (Str == "word") 1525 DestWidth = S.Context.Target.getPointerWidth(0); 1526 else if (Str == "byte") 1527 DestWidth = S.Context.Target.getCharWidth(); 1528 break; 1529 case 7: 1530 if (Str == "pointer") 1531 DestWidth = S.Context.Target.getPointerWidth(0); 1532 break; 1533 } 1534 1535 QualType OldTy; 1536 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1537 OldTy = TD->getUnderlyingType(); 1538 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1539 OldTy = VD->getType(); 1540 else { 1541 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1542 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1543 return; 1544 } 1545 1546 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 1547 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1548 else if (IntegerMode) { 1549 if (!OldTy->isIntegralType()) 1550 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1551 } else if (ComplexMode) { 1552 if (!OldTy->isComplexType()) 1553 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1554 } else { 1555 if (!OldTy->isFloatingType()) 1556 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1557 } 1558 1559 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1560 // and friends, at least with glibc. 1561 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1562 // width on unusual platforms. 1563 // FIXME: Make sure floating-point mappings are accurate 1564 // FIXME: Support XF and TF types 1565 QualType NewTy; 1566 switch (DestWidth) { 1567 case 0: 1568 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1569 return; 1570 default: 1571 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1572 return; 1573 case 8: 1574 if (!IntegerMode) { 1575 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1576 return; 1577 } 1578 if (OldTy->isSignedIntegerType()) 1579 NewTy = S.Context.SignedCharTy; 1580 else 1581 NewTy = S.Context.UnsignedCharTy; 1582 break; 1583 case 16: 1584 if (!IntegerMode) { 1585 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1586 return; 1587 } 1588 if (OldTy->isSignedIntegerType()) 1589 NewTy = S.Context.ShortTy; 1590 else 1591 NewTy = S.Context.UnsignedShortTy; 1592 break; 1593 case 32: 1594 if (!IntegerMode) 1595 NewTy = S.Context.FloatTy; 1596 else if (OldTy->isSignedIntegerType()) 1597 NewTy = S.Context.IntTy; 1598 else 1599 NewTy = S.Context.UnsignedIntTy; 1600 break; 1601 case 64: 1602 if (!IntegerMode) 1603 NewTy = S.Context.DoubleTy; 1604 else if (OldTy->isSignedIntegerType()) 1605 NewTy = S.Context.LongLongTy; 1606 else 1607 NewTy = S.Context.UnsignedLongLongTy; 1608 break; 1609 case 96: 1610 NewTy = S.Context.LongDoubleTy; 1611 break; 1612 case 128: 1613 if (!IntegerMode) { 1614 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1615 return; 1616 } 1617 NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 1618 break; 1619 } 1620 1621 if (ComplexMode) { 1622 NewTy = S.Context.getComplexType(NewTy); 1623 } 1624 1625 // Install the new type. 1626 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1627 // FIXME: preserve existing source info. 1628 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 1629 } else 1630 cast<ValueDecl>(D)->setType(NewTy); 1631} 1632 1633static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1634 // check the attribute arguments. 1635 if (Attr.getNumArgs() > 0) { 1636 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1637 return; 1638 } 1639 1640 if (!isFunctionOrMethod(d)) { 1641 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1642 << Attr.getName() << 0 /*function*/; 1643 return; 1644 } 1645 1646 d->addAttr(::new (S.Context) NoDebugAttr()); 1647} 1648 1649static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1650 // check the attribute arguments. 1651 if (Attr.getNumArgs() != 0) { 1652 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1653 return; 1654 } 1655 1656 if (!isa<FunctionDecl>(d)) { 1657 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1658 << Attr.getName() << 0 /*function*/; 1659 return; 1660 } 1661 1662 d->addAttr(::new (S.Context) NoInlineAttr()); 1663} 1664 1665static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1666 // check the attribute arguments. 1667 if (Attr.getNumArgs() != 0) { 1668 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1669 return; 1670 } 1671 1672 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1673 if (Fn == 0) { 1674 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1675 << Attr.getName() << 0 /*function*/; 1676 return; 1677 } 1678 1679 if (!Fn->isInlineSpecified()) { 1680 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1681 return; 1682 } 1683 1684 d->addAttr(::new (S.Context) GNUInlineAttr()); 1685} 1686 1687static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1688 // check the attribute arguments. 1689 if (Attr.getNumArgs() != 1) { 1690 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1691 return; 1692 } 1693 1694 if (!isFunctionOrMethod(d)) { 1695 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1696 << Attr.getName() << 0 /*function*/; 1697 return; 1698 } 1699 1700 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 1701 llvm::APSInt NumParams(32); 1702 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 1703 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1704 << "regparm" << NumParamsExpr->getSourceRange(); 1705 return; 1706 } 1707 1708 if (S.Context.Target.getRegParmMax() == 0) { 1709 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 1710 << NumParamsExpr->getSourceRange(); 1711 return; 1712 } 1713 1714 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1715 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1716 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 1717 return; 1718 } 1719 1720 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1721} 1722 1723static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1724 // check the attribute arguments. 1725 if (Attr.getNumArgs() != 0) { 1726 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1727 return; 1728 } 1729 1730 if (!isa<CXXRecordDecl>(d) 1731 && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 1732 S.Diag(Attr.getLoc(), 1733 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1734 : diag::warn_attribute_wrong_decl_type) 1735 << Attr.getName() << 7 /*virtual method or class*/; 1736 return; 1737 } 1738 1739 // FIXME: Conform to C++0x redeclaration rules. 1740 1741 if (d->getAttr<FinalAttr>()) { 1742 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 1743 return; 1744 } 1745 1746 d->addAttr(::new (S.Context) FinalAttr()); 1747} 1748 1749//===----------------------------------------------------------------------===// 1750// C++0x member checking attributes 1751//===----------------------------------------------------------------------===// 1752 1753static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1754 if (Attr.getNumArgs() != 0) { 1755 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1756 return; 1757 } 1758 1759 if (!isa<CXXRecordDecl>(d)) { 1760 S.Diag(Attr.getLoc(), 1761 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1762 : diag::warn_attribute_wrong_decl_type) 1763 << Attr.getName() << 9 /*class*/; 1764 return; 1765 } 1766 1767 if (d->getAttr<BaseCheckAttr>()) { 1768 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 1769 return; 1770 } 1771 1772 d->addAttr(::new (S.Context) BaseCheckAttr()); 1773} 1774 1775static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1776 if (Attr.getNumArgs() != 0) { 1777 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1778 return; 1779 } 1780 1781 if (!isa<RecordDecl>(d->getDeclContext())) { 1782 // FIXME: It's not the type that's the problem 1783 S.Diag(Attr.getLoc(), 1784 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1785 : diag::warn_attribute_wrong_decl_type) 1786 << Attr.getName() << 11 /*member*/; 1787 return; 1788 } 1789 1790 // FIXME: Conform to C++0x redeclaration rules. 1791 1792 if (d->getAttr<HidingAttr>()) { 1793 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 1794 return; 1795 } 1796 1797 d->addAttr(::new (S.Context) HidingAttr()); 1798} 1799 1800static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1801 if (Attr.getNumArgs() != 0) { 1802 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1803 return; 1804 } 1805 1806 if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 1807 // FIXME: It's not the type that's the problem 1808 S.Diag(Attr.getLoc(), 1809 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1810 : diag::warn_attribute_wrong_decl_type) 1811 << Attr.getName() << 10 /*virtual method*/; 1812 return; 1813 } 1814 1815 // FIXME: Conform to C++0x redeclaration rules. 1816 1817 if (d->getAttr<OverrideAttr>()) { 1818 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 1819 return; 1820 } 1821 1822 d->addAttr(::new (S.Context) OverrideAttr()); 1823} 1824 1825//===----------------------------------------------------------------------===// 1826// Checker-specific attribute handlers. 1827//===----------------------------------------------------------------------===// 1828 1829static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1830 Sema &S) { 1831 1832 QualType RetTy; 1833 1834 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 1835 RetTy = MD->getResultType(); 1836 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 1837 RetTy = FD->getResultType(); 1838 else { 1839 SourceLocation L = Attr.getLoc(); 1840 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 1841 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 1842 return; 1843 } 1844 1845 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 1846 || RetTy->getAs<ObjCObjectPointerType>())) { 1847 SourceLocation L = Attr.getLoc(); 1848 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 1849 << SourceRange(L, L) << Attr.getName(); 1850 return; 1851 } 1852 1853 switch (Attr.getKind()) { 1854 default: 1855 assert(0 && "invalid ownership attribute"); 1856 return; 1857 case AttributeList::AT_cf_returns_retained: 1858 d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1859 return; 1860 case AttributeList::AT_ns_returns_retained: 1861 d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1862 return; 1863 }; 1864} 1865 1866//===----------------------------------------------------------------------===// 1867// Top Level Sema Entry Points 1868//===----------------------------------------------------------------------===// 1869 1870/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1871/// the attribute applies to decls. If the attribute is a type attribute, just 1872/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 1873/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 1874static void ProcessDeclAttribute(Scope *scope, Decl *D, 1875 const AttributeList &Attr, Sema &S) { 1876 if (Attr.isDeclspecAttribute()) 1877 // FIXME: Try to deal with __declspec attributes! 1878 return; 1879 switch (Attr.getKind()) { 1880 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1881 case AttributeList::AT_address_space: 1882 case AttributeList::AT_objc_gc: 1883 case AttributeList::AT_vector_size: 1884 // Ignore these, these are type attributes, handled by 1885 // ProcessTypeAttributes. 1886 break; 1887 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 1888 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1889 case AttributeList::AT_always_inline: 1890 HandleAlwaysInlineAttr (D, Attr, S); break; 1891 case AttributeList::AT_analyzer_noreturn: 1892 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 1893 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 1894 case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 1895 case AttributeList::AT_carries_dependency: 1896 HandleDependencyAttr (D, Attr, S); break; 1897 case AttributeList::AT_cdecl: HandleCDeclAttr (D, Attr, S); break; 1898 case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 1899 case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 1900 case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 1901 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 1902 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 1903 case AttributeList::AT_ext_vector_type: 1904 HandleExtVectorTypeAttr(scope, D, Attr, S); 1905 break; 1906 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1907 case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 1908 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1909 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 1910 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 1911 case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 1912 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1913 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 1914 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 1915 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 1916 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1917 case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 1918 1919 // Checker-specific. 1920 case AttributeList::AT_ns_returns_retained: 1921 case AttributeList::AT_cf_returns_retained: 1922 HandleNSReturnsRetainedAttr(D, Attr, S); break; 1923 1924 case AttributeList::AT_reqd_wg_size: 1925 HandleReqdWorkGroupSize(D, Attr, S); break; 1926 1927 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 1928 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 1929 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1930 case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 1931 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1932 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 1933 case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 1934 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1935 break; 1936 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1937 case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 1938 case AttributeList::AT_transparent_union: 1939 HandleTransparentUnionAttr(D, Attr, S); 1940 break; 1941 case AttributeList::AT_objc_exception: 1942 HandleObjCExceptionAttr(D, Attr, S); 1943 break; 1944 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1945 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 1946 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1947 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1948 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1949 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1950 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1951 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 1952 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 1953 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1954 case AttributeList::IgnoredAttribute: 1955 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 1956 // Just ignore 1957 break; 1958 default: 1959 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1960 break; 1961 } 1962} 1963 1964/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1965/// attribute list to the specified decl, ignoring any type attributes. 1966void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 1967 while (AttrList) { 1968 ProcessDeclAttribute(S, D, *AttrList, *this); 1969 AttrList = AttrList->getNext(); 1970 } 1971} 1972 1973/// DeclClonePragmaWeak - clone existing decl (maybe definition), 1974/// #pragma weak needs a non-definition decl and source may not have one 1975NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 1976 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 1977 NamedDecl *NewD = 0; 1978 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 1979 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 1980 FD->getLocation(), DeclarationName(II), 1981 FD->getType(), FD->getTypeSourceInfo()); 1982 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 1983 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 1984 VD->getLocation(), II, 1985 VD->getType(), VD->getTypeSourceInfo(), 1986 VD->getStorageClass()); 1987 } 1988 return NewD; 1989} 1990 1991/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 1992/// applied to it, possibly with an alias. 1993void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 1994 if (W.getUsed()) return; // only do this once 1995 W.setUsed(true); 1996 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 1997 IdentifierInfo *NDId = ND->getIdentifier(); 1998 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 1999 NewD->addAttr(::new (Context) AliasAttr(NDId->getName())); 2000 NewD->addAttr(::new (Context) WeakAttr()); 2001 WeakTopLevelDecl.push_back(NewD); 2002 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 2003 // to insert Decl at TU scope, sorry. 2004 DeclContext *SavedContext = CurContext; 2005 CurContext = Context.getTranslationUnitDecl(); 2006 PushOnScopeChains(NewD, S); 2007 CurContext = SavedContext; 2008 } else { // just add weak to existing 2009 ND->addAttr(::new (Context) WeakAttr()); 2010 } 2011} 2012 2013/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 2014/// it, apply them to D. This is a bit tricky because PD can have attributes 2015/// specified in many different places, and we need to find and apply them all. 2016void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 2017 // Handle #pragma weak 2018 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 2019 if (ND->hasLinkage()) { 2020 WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 2021 if (W != WeakInfo()) { 2022 // Identifier referenced by #pragma weak before it was declared 2023 DeclApplyPragmaWeak(S, ND, W); 2024 WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 2025 } 2026 } 2027 } 2028 2029 // Apply decl attributes from the DeclSpec if present. 2030 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 2031 ProcessDeclAttributeList(S, D, Attrs); 2032 2033 // Walk the declarator structure, applying decl attributes that were in a type 2034 // position to the decl itself. This handles cases like: 2035 // int *__attr__(x)** D; 2036 // when X is a decl attribute. 2037 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 2038 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 2039 ProcessDeclAttributeList(S, D, Attrs); 2040 2041 // Finally, apply any attributes on the decl itself. 2042 if (const AttributeList *Attrs = PD.getAttributes()) 2043 ProcessDeclAttributeList(S, D, Attrs); 2044} 2045 2046/// PushParsingDeclaration - Enter a new "scope" of deprecation 2047/// warnings. 2048/// 2049/// The state token we use is the start index of this scope 2050/// on the warning stack. 2051Action::ParsingDeclStackState Sema::PushParsingDeclaration() { 2052 ParsingDeclDepth++; 2053 return (ParsingDeclStackState) DelayedDeprecationWarnings.size(); 2054} 2055 2056static bool isDeclDeprecated(Decl *D) { 2057 do { 2058 if (D->hasAttr<DeprecatedAttr>()) 2059 return true; 2060 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 2061 return false; 2062} 2063 2064void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) { 2065 assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 2066 ParsingDeclDepth--; 2067 2068 if (DelayedDeprecationWarnings.empty()) 2069 return; 2070 2071 unsigned SavedIndex = (unsigned) S; 2072 assert(SavedIndex <= DelayedDeprecationWarnings.size() && 2073 "saved index is out of bounds"); 2074 2075 if (Ctx && !isDeclDeprecated(Ctx.getAs<Decl>())) { 2076 for (unsigned I = 0, E = DelayedDeprecationWarnings.size(); I != E; ++I) { 2077 SourceLocation Loc = DelayedDeprecationWarnings[I].first; 2078 NamedDecl *&ND = DelayedDeprecationWarnings[I].second; 2079 if (ND) { 2080 Diag(Loc, diag::warn_deprecated) << ND->getDeclName(); 2081 2082 // Prevent this from triggering multiple times. 2083 ND = 0; 2084 } 2085 } 2086 } 2087 2088 DelayedDeprecationWarnings.set_size(SavedIndex); 2089} 2090 2091void Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) { 2092 // Delay if we're currently parsing a declaration. 2093 if (ParsingDeclDepth) { 2094 DelayedDeprecationWarnings.push_back(std::make_pair(Loc, D)); 2095 return; 2096 } 2097 2098 // Otherwise, don't warn if our current context is deprecated. 2099 if (isDeclDeprecated(cast<Decl>(CurContext))) 2100 return; 2101 2102 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 2103} 2104