SemaDeclAttr.cpp revision 8eee119bf4f1693dde17b8552c1f9f81bf2b681e
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->getBody(); 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()) { 1414 S.Diag(FirstField->getLocation(), 1415 diag::warn_transparent_union_attribute_floating); 1416 return; 1417 } 1418 1419 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1420 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1421 for (; Field != FieldEnd; ++Field) { 1422 QualType FieldType = Field->getType(); 1423 if (S.Context.getTypeSize(FieldType) != FirstSize || 1424 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1425 // Warn if we drop the attribute. 1426 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1427 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1428 : S.Context.getTypeAlign(FieldType); 1429 S.Diag(Field->getLocation(), 1430 diag::warn_transparent_union_attribute_field_size_align) 1431 << isSize << Field->getDeclName() << FieldBits; 1432 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1433 S.Diag(FirstField->getLocation(), 1434 diag::note_transparent_union_first_field_size_align) 1435 << isSize << FirstBits; 1436 return; 1437 } 1438 } 1439 1440 RD->addAttr(::new (S.Context) TransparentUnionAttr()); 1441} 1442 1443static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1444 // check the attribute arguments. 1445 if (Attr.getNumArgs() != 1) { 1446 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1447 return; 1448 } 1449 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1450 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1451 1452 // Make sure that there is a string literal as the annotation's single 1453 // argument. 1454 if (!SE) { 1455 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 1456 return; 1457 } 1458 d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString())); 1459} 1460 1461static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1462 // check the attribute arguments. 1463 if (Attr.getNumArgs() > 1) { 1464 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1465 return; 1466 } 1467 1468 //FIXME: The C++0x version of this attribute has more limited applicabilty 1469 // than GNU's, and should error out when it is used to specify a 1470 // weaker alignment, rather than being silently ignored. 1471 1472 unsigned Align = 0; 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 Align = 128; 1477 d->addAttr(::new (S.Context) AlignedAttr(Align)); 1478 return; 1479 } 1480 1481 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 1482 llvm::APSInt Alignment(32); 1483 if (alignmentExpr->isTypeDependent() || alignmentExpr->isValueDependent() || 1484 !alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1485 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1486 << "aligned" << alignmentExpr->getSourceRange(); 1487 return; 1488 } 1489 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1490 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1491 << alignmentExpr->getSourceRange(); 1492 return; 1493 } 1494 1495 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 1496} 1497 1498/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1499/// type. 1500/// 1501/// Despite what would be logical, the mode attribute is a decl attribute, not a 1502/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1503/// HImode, not an intermediate pointer. 1504static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1505 // This attribute isn't documented, but glibc uses it. It changes 1506 // the width of an int or unsigned int to the specified size. 1507 1508 // Check that there aren't any arguments 1509 if (Attr.getNumArgs() != 0) { 1510 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1511 return; 1512 } 1513 1514 IdentifierInfo *Name = Attr.getParameterName(); 1515 if (!Name) { 1516 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1517 return; 1518 } 1519 1520 llvm::StringRef Str = Attr.getParameterName()->getName(); 1521 1522 // Normalize the attribute name, __foo__ becomes foo. 1523 if (Str.startswith("__") && Str.endswith("__")) 1524 Str = Str.substr(2, Str.size() - 4); 1525 1526 unsigned DestWidth = 0; 1527 bool IntegerMode = true; 1528 bool ComplexMode = false; 1529 switch (Str.size()) { 1530 case 2: 1531 switch (Str[0]) { 1532 case 'Q': DestWidth = 8; break; 1533 case 'H': DestWidth = 16; break; 1534 case 'S': DestWidth = 32; break; 1535 case 'D': DestWidth = 64; break; 1536 case 'X': DestWidth = 96; break; 1537 case 'T': DestWidth = 128; break; 1538 } 1539 if (Str[1] == 'F') { 1540 IntegerMode = false; 1541 } else if (Str[1] == 'C') { 1542 IntegerMode = false; 1543 ComplexMode = true; 1544 } else if (Str[1] != 'I') { 1545 DestWidth = 0; 1546 } 1547 break; 1548 case 4: 1549 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1550 // pointer on PIC16 and other embedded platforms. 1551 if (Str == "word") 1552 DestWidth = S.Context.Target.getPointerWidth(0); 1553 else if (Str == "byte") 1554 DestWidth = S.Context.Target.getCharWidth(); 1555 break; 1556 case 7: 1557 if (Str == "pointer") 1558 DestWidth = S.Context.Target.getPointerWidth(0); 1559 break; 1560 } 1561 1562 QualType OldTy; 1563 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1564 OldTy = TD->getUnderlyingType(); 1565 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1566 OldTy = VD->getType(); 1567 else { 1568 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1569 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1570 return; 1571 } 1572 1573 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 1574 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1575 else if (IntegerMode) { 1576 if (!OldTy->isIntegralOrEnumerationType()) 1577 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1578 } else if (ComplexMode) { 1579 if (!OldTy->isComplexType()) 1580 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1581 } else { 1582 if (!OldTy->isFloatingType()) 1583 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1584 } 1585 1586 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1587 // and friends, at least with glibc. 1588 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1589 // width on unusual platforms. 1590 // FIXME: Make sure floating-point mappings are accurate 1591 // FIXME: Support XF and TF types 1592 QualType NewTy; 1593 switch (DestWidth) { 1594 case 0: 1595 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1596 return; 1597 default: 1598 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1599 return; 1600 case 8: 1601 if (!IntegerMode) { 1602 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1603 return; 1604 } 1605 if (OldTy->isSignedIntegerType()) 1606 NewTy = S.Context.SignedCharTy; 1607 else 1608 NewTy = S.Context.UnsignedCharTy; 1609 break; 1610 case 16: 1611 if (!IntegerMode) { 1612 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1613 return; 1614 } 1615 if (OldTy->isSignedIntegerType()) 1616 NewTy = S.Context.ShortTy; 1617 else 1618 NewTy = S.Context.UnsignedShortTy; 1619 break; 1620 case 32: 1621 if (!IntegerMode) 1622 NewTy = S.Context.FloatTy; 1623 else if (OldTy->isSignedIntegerType()) 1624 NewTy = S.Context.IntTy; 1625 else 1626 NewTy = S.Context.UnsignedIntTy; 1627 break; 1628 case 64: 1629 if (!IntegerMode) 1630 NewTy = S.Context.DoubleTy; 1631 else if (OldTy->isSignedIntegerType()) 1632 if (S.Context.Target.getLongWidth() == 64) 1633 NewTy = S.Context.LongTy; 1634 else 1635 NewTy = S.Context.LongLongTy; 1636 else 1637 if (S.Context.Target.getLongWidth() == 64) 1638 NewTy = S.Context.UnsignedLongTy; 1639 else 1640 NewTy = S.Context.UnsignedLongLongTy; 1641 break; 1642 case 96: 1643 NewTy = S.Context.LongDoubleTy; 1644 break; 1645 case 128: 1646 if (!IntegerMode) { 1647 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1648 return; 1649 } 1650 if (OldTy->isSignedIntegerType()) 1651 NewTy = S.Context.Int128Ty; 1652 else 1653 NewTy = S.Context.UnsignedInt128Ty; 1654 break; 1655 } 1656 1657 if (ComplexMode) { 1658 NewTy = S.Context.getComplexType(NewTy); 1659 } 1660 1661 // Install the new type. 1662 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1663 // FIXME: preserve existing source info. 1664 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 1665 } else 1666 cast<ValueDecl>(D)->setType(NewTy); 1667} 1668 1669static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1670 // check the attribute arguments. 1671 if (Attr.getNumArgs() > 0) { 1672 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1673 return; 1674 } 1675 1676 if (!isFunctionOrMethod(d)) { 1677 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1678 << Attr.getName() << 0 /*function*/; 1679 return; 1680 } 1681 1682 d->addAttr(::new (S.Context) NoDebugAttr()); 1683} 1684 1685static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1686 // check the attribute arguments. 1687 if (Attr.getNumArgs() != 0) { 1688 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1689 return; 1690 } 1691 1692 if (!isa<FunctionDecl>(d)) { 1693 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1694 << Attr.getName() << 0 /*function*/; 1695 return; 1696 } 1697 1698 d->addAttr(::new (S.Context) NoInlineAttr()); 1699} 1700 1701static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr, 1702 Sema &S) { 1703 // check the attribute arguments. 1704 if (Attr.getNumArgs() != 0) { 1705 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1706 return; 1707 } 1708 1709 if (!isa<FunctionDecl>(d)) { 1710 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1711 << Attr.getName() << 0 /*function*/; 1712 return; 1713 } 1714 1715 d->addAttr(::new (S.Context) NoInstrumentFunctionAttr()); 1716} 1717 1718static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1719 // check the attribute arguments. 1720 if (Attr.getNumArgs() != 0) { 1721 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1722 return; 1723 } 1724 1725 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1726 if (Fn == 0) { 1727 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1728 << Attr.getName() << 0 /*function*/; 1729 return; 1730 } 1731 1732 if (!Fn->isInlineSpecified()) { 1733 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1734 return; 1735 } 1736 1737 d->addAttr(::new (S.Context) GNUInlineAttr()); 1738} 1739 1740static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1741 // Diagnostic is emitted elsewhere: here we store the (valid) Attr 1742 // in the Decl node for syntactic reasoning, e.g., pretty-printing. 1743 assert(Attr.isInvalid() == false); 1744 1745 switch (Attr.getKind()) { 1746 case AttributeList::AT_fastcall: 1747 d->addAttr(::new (S.Context) FastCallAttr()); 1748 return; 1749 case AttributeList::AT_stdcall: 1750 d->addAttr(::new (S.Context) StdCallAttr()); 1751 return; 1752 case AttributeList::AT_thiscall: 1753 d->addAttr(::new (S.Context) ThisCallAttr()); 1754 case AttributeList::AT_cdecl: 1755 d->addAttr(::new (S.Context) CDeclAttr()); 1756 return; 1757 default: 1758 llvm_unreachable("unexpected attribute kind"); 1759 return; 1760 } 1761} 1762 1763static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1764 // check the attribute arguments. 1765 if (Attr.getNumArgs() != 1) { 1766 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1767 return; 1768 } 1769 1770 if (!isFunctionOrMethod(d)) { 1771 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1772 << Attr.getName() << 0 /*function*/; 1773 return; 1774 } 1775 1776 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 1777 llvm::APSInt NumParams(32); 1778 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 1779 !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 1780 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1781 << "regparm" << NumParamsExpr->getSourceRange(); 1782 return; 1783 } 1784 1785 if (S.Context.Target.getRegParmMax() == 0) { 1786 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 1787 << NumParamsExpr->getSourceRange(); 1788 return; 1789 } 1790 1791 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1792 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1793 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 1794 return; 1795 } 1796 1797 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1798} 1799 1800static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1801 // check the attribute arguments. 1802 if (Attr.getNumArgs() != 0) { 1803 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1804 return; 1805 } 1806 1807 if (!isa<CXXRecordDecl>(d) 1808 && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 1809 S.Diag(Attr.getLoc(), 1810 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1811 : diag::warn_attribute_wrong_decl_type) 1812 << Attr.getName() << 7 /*virtual method or class*/; 1813 return; 1814 } 1815 1816 // FIXME: Conform to C++0x redeclaration rules. 1817 1818 if (d->getAttr<FinalAttr>()) { 1819 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 1820 return; 1821 } 1822 1823 d->addAttr(::new (S.Context) FinalAttr()); 1824} 1825 1826//===----------------------------------------------------------------------===// 1827// C++0x member checking attributes 1828//===----------------------------------------------------------------------===// 1829 1830static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1831 if (Attr.getNumArgs() != 0) { 1832 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1833 return; 1834 } 1835 1836 if (!isa<CXXRecordDecl>(d)) { 1837 S.Diag(Attr.getLoc(), 1838 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1839 : diag::warn_attribute_wrong_decl_type) 1840 << Attr.getName() << 9 /*class*/; 1841 return; 1842 } 1843 1844 if (d->getAttr<BaseCheckAttr>()) { 1845 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 1846 return; 1847 } 1848 1849 d->addAttr(::new (S.Context) BaseCheckAttr()); 1850} 1851 1852static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1853 if (Attr.getNumArgs() != 0) { 1854 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1855 return; 1856 } 1857 1858 if (!isa<RecordDecl>(d->getDeclContext())) { 1859 // FIXME: It's not the type that's the problem 1860 S.Diag(Attr.getLoc(), 1861 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1862 : diag::warn_attribute_wrong_decl_type) 1863 << Attr.getName() << 11 /*member*/; 1864 return; 1865 } 1866 1867 // FIXME: Conform to C++0x redeclaration rules. 1868 1869 if (d->getAttr<HidingAttr>()) { 1870 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 1871 return; 1872 } 1873 1874 d->addAttr(::new (S.Context) HidingAttr()); 1875} 1876 1877static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1878 if (Attr.getNumArgs() != 0) { 1879 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1880 return; 1881 } 1882 1883 if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 1884 // FIXME: It's not the type that's the problem 1885 S.Diag(Attr.getLoc(), 1886 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1887 : diag::warn_attribute_wrong_decl_type) 1888 << Attr.getName() << 10 /*virtual method*/; 1889 return; 1890 } 1891 1892 // FIXME: Conform to C++0x redeclaration rules. 1893 1894 if (d->getAttr<OverrideAttr>()) { 1895 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 1896 return; 1897 } 1898 1899 d->addAttr(::new (S.Context) OverrideAttr()); 1900} 1901 1902//===----------------------------------------------------------------------===// 1903// Checker-specific attribute handlers. 1904//===----------------------------------------------------------------------===// 1905 1906static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1907 Sema &S) { 1908 1909 QualType RetTy; 1910 1911 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 1912 RetTy = MD->getResultType(); 1913 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 1914 RetTy = FD->getResultType(); 1915 else { 1916 SourceLocation L = Attr.getLoc(); 1917 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 1918 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 1919 return; 1920 } 1921 1922 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 1923 || RetTy->getAs<ObjCObjectPointerType>())) { 1924 SourceLocation L = Attr.getLoc(); 1925 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 1926 << SourceRange(L, L) << Attr.getName(); 1927 return; 1928 } 1929 1930 switch (Attr.getKind()) { 1931 default: 1932 assert(0 && "invalid ownership attribute"); 1933 return; 1934 case AttributeList::AT_cf_returns_not_retained: 1935 d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr()); 1936 return; 1937 case AttributeList::AT_ns_returns_not_retained: 1938 d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr()); 1939 return; 1940 case AttributeList::AT_cf_returns_retained: 1941 d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1942 return; 1943 case AttributeList::AT_ns_returns_retained: 1944 d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1945 return; 1946 }; 1947} 1948 1949static bool isKnownDeclSpecAttr(const AttributeList &Attr) { 1950 return Attr.getKind() == AttributeList::AT_dllimport || 1951 Attr.getKind() == AttributeList::AT_dllexport; 1952} 1953 1954//===----------------------------------------------------------------------===// 1955// Top Level Sema Entry Points 1956//===----------------------------------------------------------------------===// 1957 1958/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1959/// the attribute applies to decls. If the attribute is a type attribute, just 1960/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 1961/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 1962static void ProcessDeclAttribute(Scope *scope, Decl *D, 1963 const AttributeList &Attr, Sema &S) { 1964 if (Attr.isInvalid()) 1965 return; 1966 1967 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 1968 // FIXME: Try to deal with other __declspec attributes! 1969 return; 1970 switch (Attr.getKind()) { 1971 case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 1972 case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 1973 case AttributeList::AT_IBOutletCollection: 1974 HandleIBOutletCollection(D, Attr, S); break; 1975 case AttributeList::AT_address_space: 1976 case AttributeList::AT_objc_gc: 1977 case AttributeList::AT_vector_size: 1978 // Ignore these, these are type attributes, handled by 1979 // ProcessTypeAttributes. 1980 break; 1981 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 1982 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1983 case AttributeList::AT_always_inline: 1984 HandleAlwaysInlineAttr (D, Attr, S); break; 1985 case AttributeList::AT_analyzer_noreturn: 1986 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 1987 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 1988 case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 1989 case AttributeList::AT_carries_dependency: 1990 HandleDependencyAttr (D, Attr, S); break; 1991 case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 1992 case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 1993 case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 1994 case AttributeList::AT_ext_vector_type: 1995 HandleExtVectorTypeAttr(scope, D, Attr, S); 1996 break; 1997 case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 1998 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1999 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 2000 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 2001 case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 2002 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 2003 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 2004 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 2005 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 2006 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 2007 case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 2008 2009 // Checker-specific. 2010 case AttributeList::AT_ns_returns_not_retained: 2011 case AttributeList::AT_cf_returns_not_retained: 2012 case AttributeList::AT_ns_returns_retained: 2013 case AttributeList::AT_cf_returns_retained: 2014 HandleNSReturnsRetainedAttr(D, Attr, S); break; 2015 2016 case AttributeList::AT_reqd_wg_size: 2017 HandleReqdWorkGroupSize(D, Attr, S); break; 2018 2019 case AttributeList::AT_init_priority: 2020 HandleInitPriorityAttr(D, Attr, S); break; 2021 2022 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 2023 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 2024 case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 2025 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 2026 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 2027 case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 2028 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 2029 break; 2030 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 2031 case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 2032 case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 2033 case AttributeList::AT_transparent_union: 2034 HandleTransparentUnionAttr(D, Attr, S); 2035 break; 2036 case AttributeList::AT_objc_exception: 2037 HandleObjCExceptionAttr(D, Attr, S); 2038 break; 2039 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 2040 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 2041 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 2042 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 2043 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 2044 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 2045 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 2046 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 2047 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 2048 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 2049 case AttributeList::IgnoredAttribute: 2050 // Just ignore 2051 break; 2052 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 2053 HandleNoInstrumentFunctionAttr(D, Attr, S); 2054 break; 2055 case AttributeList::AT_stdcall: 2056 case AttributeList::AT_cdecl: 2057 case AttributeList::AT_fastcall: 2058 case AttributeList::AT_thiscall: 2059 HandleCallConvAttr(D, Attr, S); 2060 break; 2061 default: 2062 // Ask target about the attribute. 2063 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 2064 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 2065 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2066 break; 2067 } 2068} 2069 2070/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 2071/// attribute list to the specified decl, ignoring any type attributes. 2072void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 2073 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 2074 ProcessDeclAttribute(S, D, *l, *this); 2075 } 2076 2077 // GCC accepts 2078 // static int a9 __attribute__((weakref)); 2079 // but that looks really pointless. We reject it. 2080 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 2081 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 2082 dyn_cast<NamedDecl>(D)->getNameAsString(); 2083 return; 2084 } 2085} 2086 2087/// DeclClonePragmaWeak - clone existing decl (maybe definition), 2088/// #pragma weak needs a non-definition decl and source may not have one 2089NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 2090 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 2091 NamedDecl *NewD = 0; 2092 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 2093 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 2094 FD->getLocation(), DeclarationName(II), 2095 FD->getType(), FD->getTypeSourceInfo()); 2096 if (FD->getQualifier()) { 2097 FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 2098 NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 2099 } 2100 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 2101 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 2102 VD->getLocation(), II, 2103 VD->getType(), VD->getTypeSourceInfo(), 2104 VD->getStorageClass(), 2105 VD->getStorageClassAsWritten()); 2106 if (VD->getQualifier()) { 2107 VarDecl *NewVD = cast<VarDecl>(NewD); 2108 NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 2109 } 2110 } 2111 return NewD; 2112} 2113 2114/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 2115/// applied to it, possibly with an alias. 2116void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 2117 if (W.getUsed()) return; // only do this once 2118 W.setUsed(true); 2119 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 2120 IdentifierInfo *NDId = ND->getIdentifier(); 2121 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 2122 NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName())); 2123 NewD->addAttr(::new (Context) WeakAttr()); 2124 WeakTopLevelDecl.push_back(NewD); 2125 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 2126 // to insert Decl at TU scope, sorry. 2127 DeclContext *SavedContext = CurContext; 2128 CurContext = Context.getTranslationUnitDecl(); 2129 PushOnScopeChains(NewD, S); 2130 CurContext = SavedContext; 2131 } else { // just add weak to existing 2132 ND->addAttr(::new (Context) WeakAttr()); 2133 } 2134} 2135 2136/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 2137/// it, apply them to D. This is a bit tricky because PD can have attributes 2138/// specified in many different places, and we need to find and apply them all. 2139void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 2140 // Handle #pragma weak 2141 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 2142 if (ND->hasLinkage()) { 2143 WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 2144 if (W != WeakInfo()) { 2145 // Identifier referenced by #pragma weak before it was declared 2146 DeclApplyPragmaWeak(S, ND, W); 2147 WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 2148 } 2149 } 2150 } 2151 2152 // Apply decl attributes from the DeclSpec if present. 2153 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 2154 ProcessDeclAttributeList(S, D, Attrs); 2155 2156 // Walk the declarator structure, applying decl attributes that were in a type 2157 // position to the decl itself. This handles cases like: 2158 // int *__attr__(x)** D; 2159 // when X is a decl attribute. 2160 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 2161 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 2162 ProcessDeclAttributeList(S, D, Attrs); 2163 2164 // Finally, apply any attributes on the decl itself. 2165 if (const AttributeList *Attrs = PD.getAttributes()) 2166 ProcessDeclAttributeList(S, D, Attrs); 2167} 2168 2169/// PushParsingDeclaration - Enter a new "scope" of deprecation 2170/// warnings. 2171/// 2172/// The state token we use is the start index of this scope 2173/// on the warning stack. 2174Action::ParsingDeclStackState Sema::PushParsingDeclaration() { 2175 ParsingDeclDepth++; 2176 return (ParsingDeclStackState) DelayedDiagnostics.size(); 2177} 2178 2179void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) { 2180 assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 2181 ParsingDeclDepth--; 2182 2183 if (DelayedDiagnostics.empty()) 2184 return; 2185 2186 unsigned SavedIndex = (unsigned) S; 2187 assert(SavedIndex <= DelayedDiagnostics.size() && 2188 "saved index is out of bounds"); 2189 2190 unsigned E = DelayedDiagnostics.size(); 2191 2192 // We only want to actually emit delayed diagnostics when we 2193 // successfully parsed a decl. 2194 Decl *D = Ctx ? Ctx.getAs<Decl>() : 0; 2195 if (D) { 2196 // We really do want to start with 0 here. We get one push for a 2197 // decl spec and another for each declarator; in a decl group like: 2198 // deprecated_typedef foo, *bar, baz(); 2199 // only the declarator pops will be passed decls. This is correct; 2200 // we really do need to consider delayed diagnostics from the decl spec 2201 // for each of the different declarations. 2202 for (unsigned I = 0; I != E; ++I) { 2203 if (DelayedDiagnostics[I].Triggered) 2204 continue; 2205 2206 switch (DelayedDiagnostics[I].Kind) { 2207 case DelayedDiagnostic::Deprecation: 2208 HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 2209 break; 2210 2211 case DelayedDiagnostic::Access: 2212 HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 2213 break; 2214 } 2215 } 2216 } 2217 2218 // Destroy all the delayed diagnostics we're about to pop off. 2219 for (unsigned I = SavedIndex; I != E; ++I) 2220 DelayedDiagnostics[I].destroy(); 2221 2222 DelayedDiagnostics.set_size(SavedIndex); 2223} 2224 2225static bool isDeclDeprecated(Decl *D) { 2226 do { 2227 if (D->hasAttr<DeprecatedAttr>()) 2228 return true; 2229 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 2230 return false; 2231} 2232 2233void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD, 2234 Decl *Ctx) { 2235 if (isDeclDeprecated(Ctx)) 2236 return; 2237 2238 DD.Triggered = true; 2239 Diag(DD.Loc, diag::warn_deprecated) 2240 << DD.DeprecationData.Decl->getDeclName(); 2241} 2242 2243void Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) { 2244 // Delay if we're currently parsing a declaration. 2245 if (ParsingDeclDepth) { 2246 DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D)); 2247 return; 2248 } 2249 2250 // Otherwise, don't warn if our current context is deprecated. 2251 if (isDeclDeprecated(cast<Decl>(CurContext))) 2252 return; 2253 2254 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 2255} 2256