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