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