SemaDeclAttr.cpp revision 7b381985353304a7723acb05911ff91634fa1f27
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 "clang/Sema/SemaInternal.h" 15#include "TargetAttributesSema.h" 16#include "clang/AST/ASTContext.h" 17#include "clang/AST/DeclCXX.h" 18#include "clang/AST/DeclObjC.h" 19#include "clang/AST/Expr.h" 20#include "clang/Basic/TargetInfo.h" 21#include "clang/Sema/DeclSpec.h" 22#include "clang/Sema/DelayedDiagnostic.h" 23#include "llvm/ADT/StringExtras.h" 24using namespace clang; 25using namespace sema; 26 27//===----------------------------------------------------------------------===// 28// Helper functions 29//===----------------------------------------------------------------------===// 30 31static const FunctionType *getFunctionType(const Decl *d, 32 bool blocksToo = true) { 33 QualType Ty; 34 if (const ValueDecl *decl = dyn_cast<ValueDecl>(d)) 35 Ty = decl->getType(); 36 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d)) 37 Ty = decl->getType(); 38 else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 39 Ty = decl->getUnderlyingType(); 40 else 41 return 0; 42 43 if (Ty->isFunctionPointerType()) 44 Ty = Ty->getAs<PointerType>()->getPointeeType(); 45 else if (blocksToo && Ty->isBlockPointerType()) 46 Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 47 48 return Ty->getAs<FunctionType>(); 49} 50 51// FIXME: We should provide an abstraction around a method or function 52// to provide the following bits of information. 53 54/// isFunction - Return true if the given decl has function 55/// type (function or function-typed variable). 56static bool isFunction(const Decl *d) { 57 return getFunctionType(d, false) != NULL; 58} 59 60/// isFunctionOrMethod - Return true if the given decl has function 61/// type (function or function-typed variable) or an Objective-C 62/// method. 63static bool isFunctionOrMethod(const Decl *d) { 64 return isFunction(d)|| isa<ObjCMethodDecl>(d); 65} 66 67/// isFunctionOrMethodOrBlock - Return true if the given decl has function 68/// type (function or function-typed variable) or an Objective-C 69/// method or a block. 70static bool isFunctionOrMethodOrBlock(const Decl *d) { 71 if (isFunctionOrMethod(d)) 72 return true; 73 // check for block is more involved. 74 if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 75 QualType Ty = V->getType(); 76 return Ty->isBlockPointerType(); 77 } 78 return isa<BlockDecl>(d); 79} 80 81/// hasFunctionProto - Return true if the given decl has a argument 82/// information. This decl should have already passed 83/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 84static bool hasFunctionProto(const Decl *d) { 85 if (const FunctionType *FnTy = getFunctionType(d)) 86 return isa<FunctionProtoType>(FnTy); 87 else { 88 assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 89 return true; 90 } 91} 92 93/// getFunctionOrMethodNumArgs - Return number of function or method 94/// arguments. It is an error to call this on a K&R function (use 95/// hasFunctionProto first). 96static unsigned getFunctionOrMethodNumArgs(const Decl *d) { 97 if (const FunctionType *FnTy = getFunctionType(d)) 98 return cast<FunctionProtoType>(FnTy)->getNumArgs(); 99 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 100 return BD->getNumParams(); 101 return cast<ObjCMethodDecl>(d)->param_size(); 102} 103 104static QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) { 105 if (const FunctionType *FnTy = getFunctionType(d)) 106 return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 107 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 108 return BD->getParamDecl(Idx)->getType(); 109 110 return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 111} 112 113static QualType getFunctionOrMethodResultType(const Decl *d) { 114 if (const FunctionType *FnTy = getFunctionType(d)) 115 return cast<FunctionProtoType>(FnTy)->getResultType(); 116 return cast<ObjCMethodDecl>(d)->getResultType(); 117} 118 119static bool isFunctionOrMethodVariadic(const Decl *d) { 120 if (const FunctionType *FnTy = getFunctionType(d)) { 121 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 122 return proto->isVariadic(); 123 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 124 return BD->isVariadic(); 125 else { 126 return cast<ObjCMethodDecl>(d)->isVariadic(); 127 } 128} 129 130static bool isInstanceMethod(const Decl *d) { 131 if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(d)) 132 return MethodDecl->isInstance(); 133 return false; 134} 135 136static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 137 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 138 if (!PT) 139 return false; 140 141 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 142 if (!Cls) 143 return false; 144 145 IdentifierInfo* ClsName = Cls->getIdentifier(); 146 147 // FIXME: Should we walk the chain of classes? 148 return ClsName == &Ctx.Idents.get("NSString") || 149 ClsName == &Ctx.Idents.get("NSMutableString"); 150} 151 152static inline bool isCFStringType(QualType T, ASTContext &Ctx) { 153 const PointerType *PT = T->getAs<PointerType>(); 154 if (!PT) 155 return false; 156 157 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 158 if (!RT) 159 return false; 160 161 const RecordDecl *RD = RT->getDecl(); 162 if (RD->getTagKind() != TTK_Struct) 163 return false; 164 165 return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 166} 167 168//===----------------------------------------------------------------------===// 169// Attribute Implementations 170//===----------------------------------------------------------------------===// 171 172// FIXME: All this manual attribute parsing code is gross. At the 173// least add some helper functions to check most argument patterns (# 174// and types of args). 175 176static void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 177 const AttributeList &Attr, Sema &S) { 178 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 179 if (tDecl == 0) { 180 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 181 return; 182 } 183 184 QualType curType = tDecl->getUnderlyingType(); 185 186 Expr *sizeExpr; 187 188 // Special case where the argument is a template id. 189 if (Attr.getParameterName()) { 190 CXXScopeSpec SS; 191 UnqualifiedId id; 192 id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 193 sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); 194 } else { 195 // check the attribute arguments. 196 if (Attr.getNumArgs() != 1) { 197 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 198 return; 199 } 200 sizeExpr = Attr.getArg(0); 201 } 202 203 // Instantiate/Install the vector type, and let Sema build the type for us. 204 // This will run the reguired checks. 205 QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 206 if (!T.isNull()) { 207 // FIXME: preserve the old source info. 208 tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 209 210 // Remember this typedef decl, we will need it later for diagnostics. 211 S.ExtVectorDecls.push_back(tDecl); 212 } 213} 214 215static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 216 // check the attribute arguments. 217 if (Attr.getNumArgs() > 0) { 218 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 219 return; 220 } 221 222 if (TagDecl *TD = dyn_cast<TagDecl>(d)) 223 TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 224 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 225 // If the alignment is less than or equal to 8 bits, the packed attribute 226 // has no effect. 227 if (!FD->getType()->isIncompleteType() && 228 S.Context.getTypeAlign(FD->getType()) <= 8) 229 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 230 << Attr.getName() << FD->getType(); 231 else 232 FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 233 } else 234 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 235} 236 237static void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) { 238 // check the attribute arguments. 239 if (Attr.getNumArgs() > 0) { 240 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 241 return; 242 } 243 244 // The IBAction attributes only apply to instance methods. 245 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 246 if (MD->isInstanceMethod()) { 247 d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context)); 248 return; 249 } 250 251 S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName(); 252} 253 254static void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) { 255 // check the attribute arguments. 256 if (Attr.getNumArgs() > 0) { 257 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 258 return; 259 } 260 261 // The IBOutlet attributes only apply to instance variables of 262 // Objective-C classes. 263 if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) { 264 d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context)); 265 return; 266 } 267 268 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 269} 270 271static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr, 272 Sema &S) { 273 274 // The iboutletcollection attribute can have zero or one arguments. 275 if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 276 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 277 return; 278 } 279 280 // The IBOutletCollection attributes only apply to instance variables of 281 // Objective-C classes. 282 if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) { 283 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 284 return; 285 } 286 if (const ValueDecl *VD = dyn_cast<ValueDecl>(d)) 287 if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 288 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 289 << VD->getType() << 0; 290 return; 291 } 292 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d)) 293 if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 294 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 295 << PD->getType() << 1; 296 return; 297 } 298 299 IdentifierInfo *II = Attr.getParameterName(); 300 if (!II) 301 II = &S.Context.Idents.get("id"); 302 303 ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 304 S.getScopeForContext(d->getDeclContext()->getParent())); 305 if (!TypeRep) { 306 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 307 return; 308 } 309 QualType QT = TypeRep.get(); 310 // Diagnose use of non-object type in iboutletcollection attribute. 311 // FIXME. Gnu attribute extension ignores use of builtin types in 312 // attributes. So, __attribute__((iboutletcollection(char))) will be 313 // treated as __attribute__((iboutletcollection())). 314 if (!QT->isObjCIdType() && !QT->isObjCClassType() && 315 !QT->isObjCObjectType()) { 316 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 317 return; 318 } 319 d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context, 320 QT)); 321} 322 323static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 324 // GCC ignores the nonnull attribute on K&R style function prototypes, so we 325 // ignore it as well 326 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 327 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 328 << Attr.getName() << 0 /*function*/; 329 return; 330 } 331 332 // In C++ the implicit 'this' function parameter also counts, and they are 333 // counted from one. 334 bool HasImplicitThisParam = isInstanceMethod(d); 335 unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 336 337 // The nonnull attribute only applies to pointers. 338 llvm::SmallVector<unsigned, 10> NonNullArgs; 339 340 for (AttributeList::arg_iterator I=Attr.arg_begin(), 341 E=Attr.arg_end(); I!=E; ++I) { 342 343 344 // The argument must be an integer constant expression. 345 Expr *Ex = *I; 346 llvm::APSInt ArgNum(32); 347 if (Ex->isTypeDependent() || Ex->isValueDependent() || 348 !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 349 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 350 << "nonnull" << Ex->getSourceRange(); 351 return; 352 } 353 354 unsigned x = (unsigned) ArgNum.getZExtValue(); 355 356 if (x < 1 || x > NumArgs) { 357 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 358 << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 359 return; 360 } 361 362 --x; 363 if (HasImplicitThisParam) { 364 if (x == 0) { 365 S.Diag(Attr.getLoc(), 366 diag::err_attribute_invalid_implicit_this_argument) 367 << "nonnull" << Ex->getSourceRange(); 368 return; 369 } 370 --x; 371 } 372 373 // Is the function argument a pointer type? 374 QualType T = getFunctionOrMethodArgType(d, x); 375 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 376 // FIXME: Should also highlight argument in decl. 377 S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 378 << "nonnull" << Ex->getSourceRange(); 379 continue; 380 } 381 382 NonNullArgs.push_back(x); 383 } 384 385 // If no arguments were specified to __attribute__((nonnull)) then all pointer 386 // arguments have a nonnull attribute. 387 if (NonNullArgs.empty()) { 388 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 389 QualType T = getFunctionOrMethodArgType(d, I); 390 if (T->isAnyPointerType() || T->isBlockPointerType()) 391 NonNullArgs.push_back(I); 392 else if (const RecordType *UT = T->getAsUnionType()) { 393 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 394 RecordDecl *UD = UT->getDecl(); 395 for (RecordDecl::field_iterator it = UD->field_begin(), 396 itend = UD->field_end(); it != itend; ++it) { 397 T = it->getType(); 398 if (T->isAnyPointerType() || T->isBlockPointerType()) { 399 NonNullArgs.push_back(I); 400 break; 401 } 402 } 403 } 404 } 405 } 406 407 // No pointer arguments? 408 if (NonNullArgs.empty()) { 409 // Warn the trivial case only if attribute is not coming from a 410 // macro instantiation. 411 if (Attr.getLoc().isFileID()) 412 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 413 return; 414 } 415 } 416 417 unsigned* start = &NonNullArgs[0]; 418 unsigned size = NonNullArgs.size(); 419 llvm::array_pod_sort(start, start + size); 420 d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start, 421 size)); 422} 423 424static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) { 425 // This attribute must be applied to a function declaration. 426 // The first argument to the attribute must be a string, 427 // the name of the resource, for example "malloc". 428 // The following arguments must be argument indexes, the arguments must be 429 // of integer type for Returns, otherwise of pointer type. 430 // The difference between Holds and Takes is that a pointer may still be used 431 // after being held. free() should be __attribute((ownership_takes)), whereas 432 // a list append function may well be __attribute((ownership_holds)). 433 434 if (!AL.getParameterName()) { 435 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 436 << AL.getName()->getName() << 1; 437 return; 438 } 439 // Figure out our Kind, and check arguments while we're at it. 440 OwnershipAttr::OwnershipKind K; 441 switch (AL.getKind()) { 442 case AttributeList::AT_ownership_takes: 443 K = OwnershipAttr::Takes; 444 if (AL.getNumArgs() < 1) { 445 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 446 return; 447 } 448 break; 449 case AttributeList::AT_ownership_holds: 450 K = OwnershipAttr::Holds; 451 if (AL.getNumArgs() < 1) { 452 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 453 return; 454 } 455 break; 456 case AttributeList::AT_ownership_returns: 457 K = OwnershipAttr::Returns; 458 if (AL.getNumArgs() > 1) { 459 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 460 << AL.getNumArgs() + 1; 461 return; 462 } 463 break; 464 default: 465 // This should never happen given how we are called. 466 llvm_unreachable("Unknown ownership attribute"); 467 } 468 469 if (!isFunction(d) || !hasFunctionProto(d)) { 470 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName() 471 << 0 /*function*/; 472 return; 473 } 474 475 // In C++ the implicit 'this' function parameter also counts, and they are 476 // counted from one. 477 bool HasImplicitThisParam = isInstanceMethod(d); 478 unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 479 480 llvm::StringRef Module = AL.getParameterName()->getName(); 481 482 // Normalize the argument, __foo__ becomes foo. 483 if (Module.startswith("__") && Module.endswith("__")) 484 Module = Module.substr(2, Module.size() - 4); 485 486 llvm::SmallVector<unsigned, 10> OwnershipArgs; 487 488 for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 489 ++I) { 490 491 Expr *IdxExpr = *I; 492 llvm::APSInt ArgNum(32); 493 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 494 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 495 S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 496 << AL.getName()->getName() << IdxExpr->getSourceRange(); 497 continue; 498 } 499 500 unsigned x = (unsigned) ArgNum.getZExtValue(); 501 502 if (x > NumArgs || x < 1) { 503 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 504 << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 505 continue; 506 } 507 --x; 508 if (HasImplicitThisParam) { 509 if (x == 0) { 510 S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 511 << "ownership" << IdxExpr->getSourceRange(); 512 return; 513 } 514 --x; 515 } 516 517 switch (K) { 518 case OwnershipAttr::Takes: 519 case OwnershipAttr::Holds: { 520 // Is the function argument a pointer type? 521 QualType T = getFunctionOrMethodArgType(d, x); 522 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 523 // FIXME: Should also highlight argument in decl. 524 S.Diag(AL.getLoc(), diag::err_ownership_type) 525 << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 526 << "pointer" 527 << IdxExpr->getSourceRange(); 528 continue; 529 } 530 break; 531 } 532 case OwnershipAttr::Returns: { 533 if (AL.getNumArgs() > 1) { 534 // Is the function argument an integer type? 535 Expr *IdxExpr = AL.getArg(0); 536 llvm::APSInt ArgNum(32); 537 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 538 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 539 S.Diag(AL.getLoc(), diag::err_ownership_type) 540 << "ownership_returns" << "integer" 541 << IdxExpr->getSourceRange(); 542 return; 543 } 544 } 545 break; 546 } 547 default: 548 llvm_unreachable("Unknown ownership attribute"); 549 } // switch 550 551 // Check we don't have a conflict with another ownership attribute. 552 for (specific_attr_iterator<OwnershipAttr> 553 i = d->specific_attr_begin<OwnershipAttr>(), 554 e = d->specific_attr_end<OwnershipAttr>(); 555 i != e; ++i) { 556 if ((*i)->getOwnKind() != K) { 557 for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 558 I!=E; ++I) { 559 if (x == *I) { 560 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 561 << AL.getName()->getName() << "ownership_*"; 562 } 563 } 564 } 565 } 566 OwnershipArgs.push_back(x); 567 } 568 569 unsigned* start = OwnershipArgs.data(); 570 unsigned size = OwnershipArgs.size(); 571 llvm::array_pod_sort(start, start + size); 572 573 if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 574 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 575 return; 576 } 577 578 d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 579 start, size)); 580} 581 582static bool isStaticVarOrStaticFunciton(Decl *D) { 583 if (VarDecl *VD = dyn_cast<VarDecl>(D)) 584 return VD->getStorageClass() == SC_Static; 585 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 586 return FD->getStorageClass() == SC_Static; 587 return false; 588} 589 590static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) { 591 // Check the attribute arguments. 592 if (Attr.getNumArgs() > 1) { 593 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 594 return; 595 } 596 597 // gcc rejects 598 // class c { 599 // static int a __attribute__((weakref ("v2"))); 600 // static int b() __attribute__((weakref ("f3"))); 601 // }; 602 // and ignores the attributes of 603 // void f(void) { 604 // static int a __attribute__((weakref ("v2"))); 605 // } 606 // we reject them 607 const DeclContext *Ctx = d->getDeclContext()->getRedeclContext(); 608 if (!Ctx->isFileContext()) { 609 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 610 dyn_cast<NamedDecl>(d)->getNameAsString(); 611 return; 612 } 613 614 // The GCC manual says 615 // 616 // At present, a declaration to which `weakref' is attached can only 617 // be `static'. 618 // 619 // It also says 620 // 621 // Without a TARGET, 622 // given as an argument to `weakref' or to `alias', `weakref' is 623 // equivalent to `weak'. 624 // 625 // gcc 4.4.1 will accept 626 // int a7 __attribute__((weakref)); 627 // as 628 // int a7 __attribute__((weak)); 629 // This looks like a bug in gcc. We reject that for now. We should revisit 630 // it if this behaviour is actually used. 631 632 if (!isStaticVarOrStaticFunciton(d)) { 633 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) << 634 dyn_cast<NamedDecl>(d)->getNameAsString(); 635 return; 636 } 637 638 // GCC rejects 639 // static ((alias ("y"), weakref)). 640 // Should we? How to check that weakref is before or after alias? 641 642 if (Attr.getNumArgs() == 1) { 643 Expr *Arg = Attr.getArg(0); 644 Arg = Arg->IgnoreParenCasts(); 645 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 646 647 if (Str == 0 || Str->isWide()) { 648 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 649 << "weakref" << 1; 650 return; 651 } 652 // GCC will accept anything as the argument of weakref. Should we 653 // check for an existing decl? 654 d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, 655 Str->getString())); 656 } 657 658 d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context)); 659} 660 661static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 662 // check the attribute arguments. 663 if (Attr.getNumArgs() != 1) { 664 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 665 return; 666 } 667 668 Expr *Arg = Attr.getArg(0); 669 Arg = Arg->IgnoreParenCasts(); 670 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 671 672 if (Str == 0 || Str->isWide()) { 673 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 674 << "alias" << 1; 675 return; 676 } 677 678 if (S.Context.Target.getTriple().getOS() == llvm::Triple::Darwin) { 679 S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 680 return; 681 } 682 683 // FIXME: check if target symbol exists in current file 684 685 d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, 686 Str->getString())); 687} 688 689static void HandleNakedAttr(Decl *d, const AttributeList &Attr, 690 Sema &S) { 691 // Check the attribute arguments. 692 if (Attr.getNumArgs() != 0) { 693 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 694 return; 695 } 696 697 if (!isa<FunctionDecl>(d)) { 698 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 699 << Attr.getName() << 0 /*function*/; 700 return; 701 } 702 703 d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context)); 704} 705 706static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 707 Sema &S) { 708 // Check the attribute arguments. 709 if (Attr.getNumArgs() != 0) { 710 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 711 return; 712 } 713 714 if (!isa<FunctionDecl>(d)) { 715 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 716 << Attr.getName() << 0 /*function*/; 717 return; 718 } 719 720 d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context)); 721} 722 723static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 724 // Check the attribute arguments. 725 if (Attr.getNumArgs() != 0) { 726 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 727 return; 728 } 729 730 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 731 QualType RetTy = FD->getResultType(); 732 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 733 d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context)); 734 return; 735 } 736 } 737 738 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 739} 740 741static void HandleMayAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 742 // check the attribute arguments. 743 if (Attr.getNumArgs() != 0) { 744 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 745 return; 746 } 747 748 d->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context)); 749} 750 751static void HandleNoCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) { 752 assert(Attr.isInvalid() == false); 753 if (isa<VarDecl>(d)) 754 d->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context)); 755 else 756 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 757 << Attr.getName() << 12 /* variable */; 758} 759 760static void HandleCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) { 761 assert(Attr.isInvalid() == false); 762 if (isa<VarDecl>(d)) 763 d->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context)); 764 else 765 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 766 << Attr.getName() << 12 /* variable */; 767} 768 769static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 770 /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */ 771 assert(Attr.isInvalid() == false); 772 d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context)); 773} 774 775static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 776 Sema &S) { 777 778 // The checking path for 'noreturn' and 'analyzer_noreturn' are different 779 // because 'analyzer_noreturn' does not impact the type. 780 781 if (Attr.getNumArgs() != 0) { 782 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 783 return; 784 } 785 786 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 787 ValueDecl *VD = dyn_cast<ValueDecl>(d); 788 if (VD == 0 || (!VD->getType()->isBlockPointerType() 789 && !VD->getType()->isFunctionPointerType())) { 790 S.Diag(Attr.getLoc(), 791 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 792 : diag::warn_attribute_wrong_decl_type) 793 << Attr.getName() << 0 /*function*/; 794 return; 795 } 796 } 797 798 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context)); 799} 800 801// PS3 PPU-specific. 802static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr, 803 Sema &S) { 804/* 805 Returning a Vector Class in Registers 806 807 According to the PPU ABI specifications, a class with a single member of 808 vector type is returned in memory when used as the return value of a function. 809 This results in inefficient code when implementing vector classes. To return 810 the value in a single vector register, add the vecreturn attribute to the 811 class definition. This attribute is also applicable to struct types. 812 813 Example: 814 815 struct Vector 816 { 817 __vector float xyzw; 818 } __attribute__((vecreturn)); 819 820 Vector Add(Vector lhs, Vector rhs) 821 { 822 Vector result; 823 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 824 return result; // This will be returned in a register 825 } 826*/ 827 if (!isa<RecordDecl>(d)) { 828 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 829 << Attr.getName() << 9 /*class*/; 830 return; 831 } 832 833 if (d->getAttr<VecReturnAttr>()) { 834 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 835 return; 836 } 837 838 RecordDecl *record = cast<RecordDecl>(d); 839 int count = 0; 840 841 if (!isa<CXXRecordDecl>(record)) { 842 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 843 return; 844 } 845 846 if (!cast<CXXRecordDecl>(record)->isPOD()) { 847 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 848 return; 849 } 850 851 for (RecordDecl::field_iterator iter = record->field_begin(); 852 iter != record->field_end(); iter++) { 853 if ((count == 1) || !iter->getType()->isVectorType()) { 854 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 855 return; 856 } 857 count++; 858 } 859 860 d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context)); 861} 862 863static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 864 if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 865 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 866 << Attr.getName() << 8 /*function, method, or parameter*/; 867 return; 868 } 869 // FIXME: Actually store the attribute on the declaration 870} 871 872static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 873 // check the attribute arguments. 874 if (Attr.getNumArgs() != 0) { 875 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 876 return; 877 } 878 879 if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) && 880 !isa<TypeDecl>(d)) { 881 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 882 << Attr.getName() << 2 /*variable and function*/; 883 return; 884 } 885 886 d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context)); 887} 888 889static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 890 // check the attribute arguments. 891 if (Attr.getNumArgs() != 0) { 892 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 893 return; 894 } 895 896 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 897 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 898 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 899 return; 900 } 901 } else if (!isFunctionOrMethod(d)) { 902 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 903 << Attr.getName() << 2 /*variable and function*/; 904 return; 905 } 906 907 d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 908} 909 910static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 911 // check the attribute arguments. 912 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 913 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 914 << "0 or 1"; 915 return; 916 } 917 918 int priority = 65535; // FIXME: Do not hardcode such constants. 919 if (Attr.getNumArgs() > 0) { 920 Expr *E = Attr.getArg(0); 921 llvm::APSInt Idx(32); 922 if (E->isTypeDependent() || E->isValueDependent() || 923 !E->isIntegerConstantExpr(Idx, S.Context)) { 924 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 925 << "constructor" << 1 << E->getSourceRange(); 926 return; 927 } 928 priority = Idx.getZExtValue(); 929 } 930 931 if (!isa<FunctionDecl>(d)) { 932 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 933 << Attr.getName() << 0 /*function*/; 934 return; 935 } 936 937 d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, 938 priority)); 939} 940 941static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 942 // check the attribute arguments. 943 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 944 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 945 << "0 or 1"; 946 return; 947 } 948 949 int priority = 65535; // FIXME: Do not hardcode such constants. 950 if (Attr.getNumArgs() > 0) { 951 Expr *E = Attr.getArg(0); 952 llvm::APSInt Idx(32); 953 if (E->isTypeDependent() || E->isValueDependent() || 954 !E->isIntegerConstantExpr(Idx, S.Context)) { 955 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 956 << "destructor" << 1 << E->getSourceRange(); 957 return; 958 } 959 priority = Idx.getZExtValue(); 960 } 961 962 if (!isa<FunctionDecl>(d)) { 963 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 964 << Attr.getName() << 0 /*function*/; 965 return; 966 } 967 968 d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, 969 priority)); 970} 971 972static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 973 // check the attribute arguments. 974 int noArgs = Attr.getNumArgs(); 975 if (noArgs > 1) { 976 S.Diag(Attr.getLoc(), 977 diag::err_attribute_wrong_number_arguments) << "0 or 1"; 978 return; 979 } 980 // Handle the case where deprecated attribute has a text message. 981 StringLiteral *SE; 982 if (noArgs == 1) { 983 Expr *ArgExpr = Attr.getArg(0); 984 SE = dyn_cast<StringLiteral>(ArgExpr); 985 if (!SE) { 986 S.Diag(ArgExpr->getLocStart(), 987 diag::err_attribute_not_string) << "deprecated"; 988 return; 989 } 990 } 991 else 992 SE = StringLiteral::CreateEmpty(S.Context, 1); 993 994 d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, 995 SE->getString())); 996} 997 998static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 999 // check the attribute arguments. 1000 int noArgs = Attr.getNumArgs(); 1001 if (noArgs > 1) { 1002 S.Diag(Attr.getLoc(), 1003 diag::err_attribute_wrong_number_arguments) << "0 or 1"; 1004 return; 1005 } 1006 // Handle the case where unavailable attribute has a text message. 1007 StringLiteral *SE; 1008 if (noArgs == 1) { 1009 Expr *ArgExpr = Attr.getArg(0); 1010 SE = dyn_cast<StringLiteral>(ArgExpr); 1011 if (!SE) { 1012 S.Diag(ArgExpr->getLocStart(), 1013 diag::err_attribute_not_string) << "unavailable"; 1014 return; 1015 } 1016 } 1017 else 1018 SE = StringLiteral::CreateEmpty(S.Context, 1); 1019 d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, 1020 SE->getString())); 1021} 1022 1023static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1024 // check the attribute arguments. 1025 if (Attr.getNumArgs() != 1) { 1026 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1027 return; 1028 } 1029 1030 Expr *Arg = Attr.getArg(0); 1031 Arg = Arg->IgnoreParenCasts(); 1032 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1033 1034 if (Str == 0 || Str->isWide()) { 1035 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1036 << "visibility" << 1; 1037 return; 1038 } 1039 1040 llvm::StringRef TypeStr = Str->getString(); 1041 VisibilityAttr::VisibilityType type; 1042 1043 if (TypeStr == "default") 1044 type = VisibilityAttr::Default; 1045 else if (TypeStr == "hidden") 1046 type = VisibilityAttr::Hidden; 1047 else if (TypeStr == "internal") 1048 type = VisibilityAttr::Hidden; // FIXME 1049 else if (TypeStr == "protected") 1050 type = VisibilityAttr::Protected; 1051 else { 1052 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 1053 return; 1054 } 1055 1056 d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type)); 1057} 1058 1059static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 1060 Sema &S) { 1061 if (Attr.getNumArgs() != 0) { 1062 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1063 return; 1064 } 1065 1066 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 1067 if (OCI == 0) { 1068 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 1069 return; 1070 } 1071 1072 D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context)); 1073} 1074 1075static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 1076 if (Attr.getNumArgs() != 0) { 1077 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1078 return; 1079 } 1080 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1081 QualType T = TD->getUnderlyingType(); 1082 if (!T->isPointerType() || 1083 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 1084 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 1085 return; 1086 } 1087 } 1088 D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context)); 1089} 1090 1091static void 1092HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1093 if (Attr.getNumArgs() != 0) { 1094 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1095 return; 1096 } 1097 1098 if (!isa<FunctionDecl>(D)) { 1099 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 1100 return; 1101 } 1102 1103 D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context)); 1104} 1105 1106static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1107 if (!Attr.getParameterName()) { 1108 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1109 << "blocks" << 1; 1110 return; 1111 } 1112 1113 if (Attr.getNumArgs() != 0) { 1114 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1115 return; 1116 } 1117 1118 BlocksAttr::BlockType type; 1119 if (Attr.getParameterName()->isStr("byref")) 1120 type = BlocksAttr::ByRef; 1121 else { 1122 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1123 << "blocks" << Attr.getParameterName(); 1124 return; 1125 } 1126 1127 d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type)); 1128} 1129 1130static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1131 // check the attribute arguments. 1132 if (Attr.getNumArgs() > 2) { 1133 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 1134 << "0, 1 or 2"; 1135 return; 1136 } 1137 1138 int sentinel = 0; 1139 if (Attr.getNumArgs() > 0) { 1140 Expr *E = Attr.getArg(0); 1141 llvm::APSInt Idx(32); 1142 if (E->isTypeDependent() || E->isValueDependent() || 1143 !E->isIntegerConstantExpr(Idx, S.Context)) { 1144 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1145 << "sentinel" << 1 << E->getSourceRange(); 1146 return; 1147 } 1148 sentinel = Idx.getZExtValue(); 1149 1150 if (sentinel < 0) { 1151 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 1152 << E->getSourceRange(); 1153 return; 1154 } 1155 } 1156 1157 int nullPos = 0; 1158 if (Attr.getNumArgs() > 1) { 1159 Expr *E = Attr.getArg(1); 1160 llvm::APSInt Idx(32); 1161 if (E->isTypeDependent() || E->isValueDependent() || 1162 !E->isIntegerConstantExpr(Idx, S.Context)) { 1163 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1164 << "sentinel" << 2 << E->getSourceRange(); 1165 return; 1166 } 1167 nullPos = Idx.getZExtValue(); 1168 1169 if (nullPos > 1 || nullPos < 0) { 1170 // FIXME: This error message could be improved, it would be nice 1171 // to say what the bounds actually are. 1172 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1173 << E->getSourceRange(); 1174 return; 1175 } 1176 } 1177 1178 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 1179 const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 1180 assert(FT && "FunctionDecl has non-function type?"); 1181 1182 if (isa<FunctionNoProtoType>(FT)) { 1183 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1184 return; 1185 } 1186 1187 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 1188 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1189 return; 1190 } 1191 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 1192 if (!MD->isVariadic()) { 1193 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1194 return; 1195 } 1196 } else if (isa<BlockDecl>(d)) { 1197 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 1198 // caller. 1199 ; 1200 } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 1201 QualType Ty = V->getType(); 1202 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 1203 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 1204 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 1205 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 1206 int m = Ty->isFunctionPointerType() ? 0 : 1; 1207 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 1208 return; 1209 } 1210 } else { 1211 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1212 << Attr.getName() << 6 /*function, method or block */; 1213 return; 1214 } 1215 } else { 1216 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1217 << Attr.getName() << 6 /*function, method or block */; 1218 return; 1219 } 1220 d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, 1221 nullPos)); 1222} 1223 1224static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 1225 // check the attribute arguments. 1226 if (Attr.getNumArgs() != 0) { 1227 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1228 return; 1229 } 1230 1231 if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1232 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1233 << Attr.getName() << 0 /*function*/; 1234 return; 1235 } 1236 1237 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1238 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1239 << Attr.getName() << 0; 1240 return; 1241 } 1242 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1243 if (MD->getResultType()->isVoidType()) { 1244 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1245 << Attr.getName() << 1; 1246 return; 1247 } 1248 1249 D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context)); 1250} 1251 1252static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1253 // check the attribute arguments. 1254 if (Attr.getNumArgs() != 0) { 1255 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1256 return; 1257 } 1258 1259 /* weak only applies to non-static declarations */ 1260 if (isStaticVarOrStaticFunciton(D)) { 1261 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 1262 dyn_cast<NamedDecl>(D)->getNameAsString(); 1263 return; 1264 } 1265 1266 // TODO: could also be applied to methods? 1267 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 1268 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1269 << Attr.getName() << 2 /*variable and function*/; 1270 return; 1271 } 1272 1273 D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context)); 1274} 1275 1276static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1277 // check the attribute arguments. 1278 if (Attr.getNumArgs() != 0) { 1279 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1280 return; 1281 } 1282 1283 // weak_import only applies to variable & function declarations. 1284 bool isDef = false; 1285 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 1286 isDef = (!VD->hasExternalStorage() || VD->getInit()); 1287 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1288 isDef = FD->hasBody(); 1289 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 1290 // We ignore weak import on properties and methods 1291 return; 1292 } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) { 1293 // Don't issue the warning for darwin as target; yet, ignore the attribute. 1294 if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin || 1295 !isa<ObjCInterfaceDecl>(D)) 1296 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1297 << Attr.getName() << 2 /*variable and function*/; 1298 return; 1299 } 1300 1301 // Merge should handle any subsequent violations. 1302 if (isDef) { 1303 S.Diag(Attr.getLoc(), 1304 diag::warn_attribute_weak_import_invalid_on_definition) 1305 << "weak_import" << 2 /*variable and function*/; 1306 return; 1307 } 1308 1309 D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context)); 1310} 1311 1312static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 1313 Sema &S) { 1314 // Attribute has 3 arguments. 1315 if (Attr.getNumArgs() != 3) { 1316 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1317 return; 1318 } 1319 1320 unsigned WGSize[3]; 1321 for (unsigned i = 0; i < 3; ++i) { 1322 Expr *E = Attr.getArg(i); 1323 llvm::APSInt ArgNum(32); 1324 if (E->isTypeDependent() || E->isValueDependent() || 1325 !E->isIntegerConstantExpr(ArgNum, S.Context)) { 1326 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1327 << "reqd_work_group_size" << E->getSourceRange(); 1328 return; 1329 } 1330 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 1331 } 1332 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context, 1333 WGSize[0], WGSize[1], 1334 WGSize[2])); 1335} 1336 1337static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1338 // Attribute has no arguments. 1339 if (Attr.getNumArgs() != 1) { 1340 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1341 return; 1342 } 1343 1344 // Make sure that there is a string literal as the sections's single 1345 // argument. 1346 Expr *ArgExpr = Attr.getArg(0); 1347 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1348 if (!SE) { 1349 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 1350 return; 1351 } 1352 1353 // If the target wants to validate the section specifier, make it happen. 1354 std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 1355 if (!Error.empty()) { 1356 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1357 << Error; 1358 return; 1359 } 1360 1361 // This attribute cannot be applied to local variables. 1362 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 1363 S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 1364 return; 1365 } 1366 1367 D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, 1368 SE->getString())); 1369} 1370 1371 1372static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1373 // check the attribute arguments. 1374 if (Attr.getNumArgs() != 0) { 1375 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1376 return; 1377 } 1378 1379 d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context)); 1380} 1381 1382static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1383 // check the attribute arguments. 1384 if (Attr.getNumArgs() != 0) { 1385 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1386 return; 1387 } 1388 1389 d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context)); 1390} 1391 1392static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1393 // check the attribute arguments. 1394 if (Attr.getNumArgs() != 0) { 1395 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1396 return; 1397 } 1398 1399 d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context)); 1400} 1401 1402static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1403 if (!Attr.getParameterName()) { 1404 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1405 return; 1406 } 1407 1408 if (Attr.getNumArgs() != 0) { 1409 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1410 return; 1411 } 1412 1413 VarDecl *VD = dyn_cast<VarDecl>(d); 1414 1415 if (!VD || !VD->hasLocalStorage()) { 1416 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1417 return; 1418 } 1419 1420 // Look up the function 1421 // FIXME: Lookup probably isn't looking in the right place 1422 NamedDecl *CleanupDecl 1423 = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 1424 Attr.getParameterLoc(), Sema::LookupOrdinaryName); 1425 if (!CleanupDecl) { 1426 S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 1427 Attr.getParameterName(); 1428 return; 1429 } 1430 1431 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1432 if (!FD) { 1433 S.Diag(Attr.getParameterLoc(), 1434 diag::err_attribute_cleanup_arg_not_function) 1435 << Attr.getParameterName(); 1436 return; 1437 } 1438 1439 if (FD->getNumParams() != 1) { 1440 S.Diag(Attr.getParameterLoc(), 1441 diag::err_attribute_cleanup_func_must_take_one_arg) 1442 << Attr.getParameterName(); 1443 return; 1444 } 1445 1446 // We're currently more strict than GCC about what function types we accept. 1447 // If this ever proves to be a problem it should be easy to fix. 1448 QualType Ty = S.Context.getPointerType(VD->getType()); 1449 QualType ParamTy = FD->getParamDecl(0)->getType(); 1450 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1451 S.Diag(Attr.getParameterLoc(), 1452 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1453 Attr.getParameterName() << ParamTy << Ty; 1454 return; 1455 } 1456 1457 d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD)); 1458 S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD); 1459} 1460 1461/// Handle __attribute__((format_arg((idx)))) attribute based on 1462/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1463static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1464 if (Attr.getNumArgs() != 1) { 1465 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1466 return; 1467 } 1468 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1469 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1470 << Attr.getName() << 0 /*function*/; 1471 return; 1472 } 1473 1474 // In C++ the implicit 'this' function parameter also counts, and they are 1475 // counted from one. 1476 bool HasImplicitThisParam = isInstanceMethod(d); 1477 unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 1478 unsigned FirstIdx = 1; 1479 1480 // checks for the 2nd argument 1481 Expr *IdxExpr = Attr.getArg(0); 1482 llvm::APSInt Idx(32); 1483 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1484 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1485 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1486 << "format" << 2 << IdxExpr->getSourceRange(); 1487 return; 1488 } 1489 1490 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1491 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1492 << "format" << 2 << IdxExpr->getSourceRange(); 1493 return; 1494 } 1495 1496 unsigned ArgIdx = Idx.getZExtValue() - 1; 1497 1498 if (HasImplicitThisParam) { 1499 if (ArgIdx == 0) { 1500 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 1501 << "format_arg" << IdxExpr->getSourceRange(); 1502 return; 1503 } 1504 ArgIdx--; 1505 } 1506 1507 // make sure the format string is really a string 1508 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1509 1510 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 1511 if (not_nsstring_type && 1512 !isCFStringType(Ty, S.Context) && 1513 (!Ty->isPointerType() || 1514 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1515 // FIXME: Should highlight the actual expression that has the wrong type. 1516 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1517 << (not_nsstring_type ? "a string type" : "an NSString") 1518 << IdxExpr->getSourceRange(); 1519 return; 1520 } 1521 Ty = getFunctionOrMethodResultType(d); 1522 if (!isNSStringType(Ty, S.Context) && 1523 !isCFStringType(Ty, S.Context) && 1524 (!Ty->isPointerType() || 1525 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1526 // FIXME: Should highlight the actual expression that has the wrong type. 1527 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1528 << (not_nsstring_type ? "string type" : "NSString") 1529 << IdxExpr->getSourceRange(); 1530 return; 1531 } 1532 1533 d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, 1534 Idx.getZExtValue())); 1535} 1536 1537enum FormatAttrKind { 1538 CFStringFormat, 1539 NSStringFormat, 1540 StrftimeFormat, 1541 SupportedFormat, 1542 IgnoredFormat, 1543 InvalidFormat 1544}; 1545 1546/// getFormatAttrKind - Map from format attribute names to supported format 1547/// types. 1548static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 1549 // Check for formats that get handled specially. 1550 if (Format == "NSString") 1551 return NSStringFormat; 1552 if (Format == "CFString") 1553 return CFStringFormat; 1554 if (Format == "strftime") 1555 return StrftimeFormat; 1556 1557 // Otherwise, check for supported formats. 1558 if (Format == "scanf" || Format == "printf" || Format == "printf0" || 1559 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 1560 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 1561 Format == "zcmn_err") 1562 return SupportedFormat; 1563 1564 if (Format == "gcc_diag" || Format == "gcc_cdiag" || 1565 Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 1566 return IgnoredFormat; 1567 1568 return InvalidFormat; 1569} 1570 1571/// Handle __attribute__((init_priority(priority))) attributes based on 1572/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 1573static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 1574 Sema &S) { 1575 if (!S.getLangOptions().CPlusPlus) { 1576 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1577 return; 1578 } 1579 1580 if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) { 1581 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1582 Attr.setInvalid(); 1583 return; 1584 } 1585 QualType T = dyn_cast<VarDecl>(d)->getType(); 1586 if (S.Context.getAsArrayType(T)) 1587 T = S.Context.getBaseElementType(T); 1588 if (!T->getAs<RecordType>()) { 1589 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1590 Attr.setInvalid(); 1591 return; 1592 } 1593 1594 if (Attr.getNumArgs() != 1) { 1595 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1596 Attr.setInvalid(); 1597 return; 1598 } 1599 Expr *priorityExpr = Attr.getArg(0); 1600 1601 llvm::APSInt priority(32); 1602 if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 1603 !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 1604 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1605 << "init_priority" << priorityExpr->getSourceRange(); 1606 Attr.setInvalid(); 1607 return; 1608 } 1609 unsigned prioritynum = priority.getZExtValue(); 1610 if (prioritynum < 101 || prioritynum > 65535) { 1611 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 1612 << priorityExpr->getSourceRange(); 1613 Attr.setInvalid(); 1614 return; 1615 } 1616 d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, 1617 prioritynum)); 1618} 1619 1620/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1621/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1622static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1623 1624 if (!Attr.getParameterName()) { 1625 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1626 << "format" << 1; 1627 return; 1628 } 1629 1630 if (Attr.getNumArgs() != 2) { 1631 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1632 return; 1633 } 1634 1635 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1636 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1637 << Attr.getName() << 0 /*function*/; 1638 return; 1639 } 1640 1641 // In C++ the implicit 'this' function parameter also counts, and they are 1642 // counted from one. 1643 bool HasImplicitThisParam = isInstanceMethod(d); 1644 unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 1645 unsigned FirstIdx = 1; 1646 1647 llvm::StringRef Format = Attr.getParameterName()->getName(); 1648 1649 // Normalize the argument, __foo__ becomes foo. 1650 if (Format.startswith("__") && Format.endswith("__")) 1651 Format = Format.substr(2, Format.size() - 4); 1652 1653 // Check for supported formats. 1654 FormatAttrKind Kind = getFormatAttrKind(Format); 1655 1656 if (Kind == IgnoredFormat) 1657 return; 1658 1659 if (Kind == InvalidFormat) { 1660 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1661 << "format" << Attr.getParameterName()->getName(); 1662 return; 1663 } 1664 1665 // checks for the 2nd argument 1666 Expr *IdxExpr = Attr.getArg(0); 1667 llvm::APSInt Idx(32); 1668 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1669 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1670 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1671 << "format" << 2 << IdxExpr->getSourceRange(); 1672 return; 1673 } 1674 1675 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1676 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1677 << "format" << 2 << IdxExpr->getSourceRange(); 1678 return; 1679 } 1680 1681 // FIXME: Do we need to bounds check? 1682 unsigned ArgIdx = Idx.getZExtValue() - 1; 1683 1684 if (HasImplicitThisParam) { 1685 if (ArgIdx == 0) { 1686 S.Diag(Attr.getLoc(), 1687 diag::err_format_attribute_implicit_this_format_string) 1688 << IdxExpr->getSourceRange(); 1689 return; 1690 } 1691 ArgIdx--; 1692 } 1693 1694 // make sure the format string is really a string 1695 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1696 1697 if (Kind == CFStringFormat) { 1698 if (!isCFStringType(Ty, S.Context)) { 1699 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1700 << "a CFString" << IdxExpr->getSourceRange(); 1701 return; 1702 } 1703 } else if (Kind == NSStringFormat) { 1704 // FIXME: do we need to check if the type is NSString*? What are the 1705 // semantics? 1706 if (!isNSStringType(Ty, S.Context)) { 1707 // FIXME: Should highlight the actual expression that has the wrong type. 1708 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1709 << "an NSString" << IdxExpr->getSourceRange(); 1710 return; 1711 } 1712 } else if (!Ty->isPointerType() || 1713 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1714 // FIXME: Should highlight the actual expression that has the wrong type. 1715 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1716 << "a string type" << IdxExpr->getSourceRange(); 1717 return; 1718 } 1719 1720 // check the 3rd argument 1721 Expr *FirstArgExpr = Attr.getArg(1); 1722 llvm::APSInt FirstArg(32); 1723 if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 1724 !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1725 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1726 << "format" << 3 << FirstArgExpr->getSourceRange(); 1727 return; 1728 } 1729 1730 // check if the function is variadic if the 3rd argument non-zero 1731 if (FirstArg != 0) { 1732 if (isFunctionOrMethodVariadic(d)) { 1733 ++NumArgs; // +1 for ... 1734 } else { 1735 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1736 return; 1737 } 1738 } 1739 1740 // strftime requires FirstArg to be 0 because it doesn't read from any 1741 // variable the input is just the current time + the format string. 1742 if (Kind == StrftimeFormat) { 1743 if (FirstArg != 0) { 1744 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1745 << FirstArgExpr->getSourceRange(); 1746 return; 1747 } 1748 // if 0 it disables parameter checking (to use with e.g. va_list) 1749 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1750 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1751 << "format" << 3 << FirstArgExpr->getSourceRange(); 1752 return; 1753 } 1754 1755 d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format, 1756 Idx.getZExtValue(), 1757 FirstArg.getZExtValue())); 1758} 1759 1760static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1761 Sema &S) { 1762 // check the attribute arguments. 1763 if (Attr.getNumArgs() != 0) { 1764 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1765 return; 1766 } 1767 1768 // Try to find the underlying union declaration. 1769 RecordDecl *RD = 0; 1770 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1771 if (TD && TD->getUnderlyingType()->isUnionType()) 1772 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1773 else 1774 RD = dyn_cast<RecordDecl>(d); 1775 1776 if (!RD || !RD->isUnion()) { 1777 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1778 << Attr.getName() << 1 /*union*/; 1779 return; 1780 } 1781 1782 if (!RD->isDefinition()) { 1783 S.Diag(Attr.getLoc(), 1784 diag::warn_transparent_union_attribute_not_definition); 1785 return; 1786 } 1787 1788 RecordDecl::field_iterator Field = RD->field_begin(), 1789 FieldEnd = RD->field_end(); 1790 if (Field == FieldEnd) { 1791 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1792 return; 1793 } 1794 1795 FieldDecl *FirstField = *Field; 1796 QualType FirstType = FirstField->getType(); 1797 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 1798 S.Diag(FirstField->getLocation(), 1799 diag::warn_transparent_union_attribute_floating) 1800 << FirstType->isVectorType() << FirstType; 1801 return; 1802 } 1803 1804 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1805 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1806 for (; Field != FieldEnd; ++Field) { 1807 QualType FieldType = Field->getType(); 1808 if (S.Context.getTypeSize(FieldType) != FirstSize || 1809 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1810 // Warn if we drop the attribute. 1811 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1812 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1813 : S.Context.getTypeAlign(FieldType); 1814 S.Diag(Field->getLocation(), 1815 diag::warn_transparent_union_attribute_field_size_align) 1816 << isSize << Field->getDeclName() << FieldBits; 1817 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1818 S.Diag(FirstField->getLocation(), 1819 diag::note_transparent_union_first_field_size_align) 1820 << isSize << FirstBits; 1821 return; 1822 } 1823 } 1824 1825 RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context)); 1826} 1827 1828static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1829 // check the attribute arguments. 1830 if (Attr.getNumArgs() != 1) { 1831 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1832 return; 1833 } 1834 Expr *ArgExpr = Attr.getArg(0); 1835 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1836 1837 // Make sure that there is a string literal as the annotation's single 1838 // argument. 1839 if (!SE) { 1840 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 1841 return; 1842 } 1843 d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, 1844 SE->getString())); 1845} 1846 1847static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1848 // check the attribute arguments. 1849 if (Attr.getNumArgs() > 1) { 1850 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1851 return; 1852 } 1853 1854 //FIXME: The C++0x version of this attribute has more limited applicabilty 1855 // than GNU's, and should error out when it is used to specify a 1856 // weaker alignment, rather than being silently ignored. 1857 1858 if (Attr.getNumArgs() == 0) { 1859 D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0)); 1860 return; 1861 } 1862 1863 S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0)); 1864} 1865 1866void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { 1867 if (E->isTypeDependent() || E->isValueDependent()) { 1868 // Save dependent expressions in the AST to be instantiated. 1869 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 1870 return; 1871 } 1872 1873 // FIXME: Cache the number on the Attr object? 1874 llvm::APSInt Alignment(32); 1875 if (!E->isIntegerConstantExpr(Alignment, Context)) { 1876 Diag(AttrLoc, diag::err_attribute_argument_not_int) 1877 << "aligned" << E->getSourceRange(); 1878 return; 1879 } 1880 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1881 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 1882 << E->getSourceRange(); 1883 return; 1884 } 1885 1886 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 1887} 1888 1889void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) { 1890 // FIXME: Cache the number on the Attr object if non-dependent? 1891 // FIXME: Perform checking of type validity 1892 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS)); 1893 return; 1894} 1895 1896/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1897/// type. 1898/// 1899/// Despite what would be logical, the mode attribute is a decl attribute, not a 1900/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1901/// HImode, not an intermediate pointer. 1902static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1903 // This attribute isn't documented, but glibc uses it. It changes 1904 // the width of an int or unsigned int to the specified size. 1905 1906 // Check that there aren't any arguments 1907 if (Attr.getNumArgs() != 0) { 1908 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1909 return; 1910 } 1911 1912 IdentifierInfo *Name = Attr.getParameterName(); 1913 if (!Name) { 1914 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1915 return; 1916 } 1917 1918 llvm::StringRef Str = Attr.getParameterName()->getName(); 1919 1920 // Normalize the attribute name, __foo__ becomes foo. 1921 if (Str.startswith("__") && Str.endswith("__")) 1922 Str = Str.substr(2, Str.size() - 4); 1923 1924 unsigned DestWidth = 0; 1925 bool IntegerMode = true; 1926 bool ComplexMode = false; 1927 switch (Str.size()) { 1928 case 2: 1929 switch (Str[0]) { 1930 case 'Q': DestWidth = 8; break; 1931 case 'H': DestWidth = 16; break; 1932 case 'S': DestWidth = 32; break; 1933 case 'D': DestWidth = 64; break; 1934 case 'X': DestWidth = 96; break; 1935 case 'T': DestWidth = 128; break; 1936 } 1937 if (Str[1] == 'F') { 1938 IntegerMode = false; 1939 } else if (Str[1] == 'C') { 1940 IntegerMode = false; 1941 ComplexMode = true; 1942 } else if (Str[1] != 'I') { 1943 DestWidth = 0; 1944 } 1945 break; 1946 case 4: 1947 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1948 // pointer on PIC16 and other embedded platforms. 1949 if (Str == "word") 1950 DestWidth = S.Context.Target.getPointerWidth(0); 1951 else if (Str == "byte") 1952 DestWidth = S.Context.Target.getCharWidth(); 1953 break; 1954 case 7: 1955 if (Str == "pointer") 1956 DestWidth = S.Context.Target.getPointerWidth(0); 1957 break; 1958 } 1959 1960 QualType OldTy; 1961 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1962 OldTy = TD->getUnderlyingType(); 1963 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1964 OldTy = VD->getType(); 1965 else { 1966 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1967 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1968 return; 1969 } 1970 1971 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 1972 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1973 else if (IntegerMode) { 1974 if (!OldTy->isIntegralOrEnumerationType()) 1975 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1976 } else if (ComplexMode) { 1977 if (!OldTy->isComplexType()) 1978 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1979 } else { 1980 if (!OldTy->isFloatingType()) 1981 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1982 } 1983 1984 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1985 // and friends, at least with glibc. 1986 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1987 // width on unusual platforms. 1988 // FIXME: Make sure floating-point mappings are accurate 1989 // FIXME: Support XF and TF types 1990 QualType NewTy; 1991 switch (DestWidth) { 1992 case 0: 1993 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1994 return; 1995 default: 1996 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1997 return; 1998 case 8: 1999 if (!IntegerMode) { 2000 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2001 return; 2002 } 2003 if (OldTy->isSignedIntegerType()) 2004 NewTy = S.Context.SignedCharTy; 2005 else 2006 NewTy = S.Context.UnsignedCharTy; 2007 break; 2008 case 16: 2009 if (!IntegerMode) { 2010 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2011 return; 2012 } 2013 if (OldTy->isSignedIntegerType()) 2014 NewTy = S.Context.ShortTy; 2015 else 2016 NewTy = S.Context.UnsignedShortTy; 2017 break; 2018 case 32: 2019 if (!IntegerMode) 2020 NewTy = S.Context.FloatTy; 2021 else if (OldTy->isSignedIntegerType()) 2022 NewTy = S.Context.IntTy; 2023 else 2024 NewTy = S.Context.UnsignedIntTy; 2025 break; 2026 case 64: 2027 if (!IntegerMode) 2028 NewTy = S.Context.DoubleTy; 2029 else if (OldTy->isSignedIntegerType()) 2030 if (S.Context.Target.getLongWidth() == 64) 2031 NewTy = S.Context.LongTy; 2032 else 2033 NewTy = S.Context.LongLongTy; 2034 else 2035 if (S.Context.Target.getLongWidth() == 64) 2036 NewTy = S.Context.UnsignedLongTy; 2037 else 2038 NewTy = S.Context.UnsignedLongLongTy; 2039 break; 2040 case 96: 2041 NewTy = S.Context.LongDoubleTy; 2042 break; 2043 case 128: 2044 if (!IntegerMode) { 2045 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2046 return; 2047 } 2048 if (OldTy->isSignedIntegerType()) 2049 NewTy = S.Context.Int128Ty; 2050 else 2051 NewTy = S.Context.UnsignedInt128Ty; 2052 break; 2053 } 2054 2055 if (ComplexMode) { 2056 NewTy = S.Context.getComplexType(NewTy); 2057 } 2058 2059 // Install the new type. 2060 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 2061 // FIXME: preserve existing source info. 2062 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 2063 } else 2064 cast<ValueDecl>(D)->setType(NewTy); 2065} 2066 2067static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2068 // check the attribute arguments. 2069 if (Attr.getNumArgs() > 0) { 2070 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2071 return; 2072 } 2073 2074 if (!isFunctionOrMethod(d)) { 2075 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2076 << Attr.getName() << 0 /*function*/; 2077 return; 2078 } 2079 2080 d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context)); 2081} 2082 2083static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2084 // check the attribute arguments. 2085 if (Attr.getNumArgs() != 0) { 2086 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2087 return; 2088 } 2089 2090 if (!isa<FunctionDecl>(d)) { 2091 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2092 << Attr.getName() << 0 /*function*/; 2093 return; 2094 } 2095 2096 d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context)); 2097} 2098 2099static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr, 2100 Sema &S) { 2101 // check the attribute arguments. 2102 if (Attr.getNumArgs() != 0) { 2103 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2104 return; 2105 } 2106 2107 if (!isa<FunctionDecl>(d)) { 2108 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2109 << Attr.getName() << 0 /*function*/; 2110 return; 2111 } 2112 2113 d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), 2114 S.Context)); 2115} 2116 2117static void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2118 if (S.LangOpts.CUDA) { 2119 // check the attribute arguments. 2120 if (Attr.getNumArgs() != 0) { 2121 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2122 return; 2123 } 2124 2125 if (!isa<VarDecl>(d)) { 2126 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2127 << Attr.getName() << 12 /*variable*/; 2128 return; 2129 } 2130 2131 d->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context)); 2132 } else { 2133 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 2134 } 2135} 2136 2137static void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2138 if (S.LangOpts.CUDA) { 2139 // check the attribute arguments. 2140 if (Attr.getNumArgs() != 0) { 2141 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2142 return; 2143 } 2144 2145 if (!isa<FunctionDecl>(d) && !isa<VarDecl>(d)) { 2146 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2147 << Attr.getName() << 2 /*variable and function*/; 2148 return; 2149 } 2150 2151 d->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context)); 2152 } else { 2153 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 2154 } 2155} 2156 2157static void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2158 if (S.LangOpts.CUDA) { 2159 // check the attribute arguments. 2160 if (Attr.getNumArgs() != 0) { 2161 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2162 return; 2163 } 2164 2165 if (!isa<FunctionDecl>(d)) { 2166 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2167 << Attr.getName() << 0 /*function*/; 2168 return; 2169 } 2170 2171 FunctionDecl *FD = cast<FunctionDecl>(d); 2172 if (!FD->getResultType()->isVoidType()) { 2173 TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc(); 2174 if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 2175 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 2176 << FD->getType() 2177 << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 2178 "void"); 2179 } else { 2180 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 2181 << FD->getType(); 2182 } 2183 return; 2184 } 2185 2186 d->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context)); 2187 } else { 2188 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 2189 } 2190} 2191 2192static void HandleHostAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2193 if (S.LangOpts.CUDA) { 2194 // check the attribute arguments. 2195 if (Attr.getNumArgs() != 0) { 2196 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2197 return; 2198 } 2199 2200 if (!isa<FunctionDecl>(d)) { 2201 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2202 << Attr.getName() << 0 /*function*/; 2203 return; 2204 } 2205 2206 d->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context)); 2207 } else { 2208 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 2209 } 2210} 2211 2212static void HandleSharedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2213 if (S.LangOpts.CUDA) { 2214 // check the attribute arguments. 2215 if (Attr.getNumArgs() != 0) { 2216 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2217 return; 2218 } 2219 2220 if (!isa<VarDecl>(d)) { 2221 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2222 << Attr.getName() << 12 /*variable*/; 2223 return; 2224 } 2225 2226 d->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context)); 2227 } else { 2228 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 2229 } 2230} 2231 2232static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2233 // check the attribute arguments. 2234 if (Attr.getNumArgs() != 0) { 2235 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2236 return; 2237 } 2238 2239 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 2240 if (Fn == 0) { 2241 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2242 << Attr.getName() << 0 /*function*/; 2243 return; 2244 } 2245 2246 if (!Fn->isInlineSpecified()) { 2247 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 2248 return; 2249 } 2250 2251 d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context)); 2252} 2253 2254static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2255 // Diagnostic is emitted elsewhere: here we store the (valid) Attr 2256 // in the Decl node for syntactic reasoning, e.g., pretty-printing. 2257 assert(Attr.isInvalid() == false); 2258 2259 switch (Attr.getKind()) { 2260 case AttributeList::AT_fastcall: 2261 d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context)); 2262 return; 2263 case AttributeList::AT_stdcall: 2264 d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context)); 2265 return; 2266 case AttributeList::AT_thiscall: 2267 d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context)); 2268 return; 2269 case AttributeList::AT_cdecl: 2270 d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context)); 2271 return; 2272 case AttributeList::AT_pascal: 2273 d->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context)); 2274 return; 2275 default: 2276 llvm_unreachable("unexpected attribute kind"); 2277 return; 2278 } 2279} 2280 2281static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2282 // check the attribute arguments. 2283 if (Attr.getNumArgs() != 1) { 2284 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2285 return; 2286 } 2287 2288 if (!isFunctionOrMethod(d)) { 2289 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2290 << Attr.getName() << 0 /*function*/; 2291 return; 2292 } 2293 2294 Expr *NumParamsExpr = Attr.getArg(0); 2295 llvm::APSInt NumParams(32); 2296 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 2297 !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 2298 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 2299 << "regparm" << NumParamsExpr->getSourceRange(); 2300 return; 2301 } 2302 2303 if (S.Context.Target.getRegParmMax() == 0) { 2304 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 2305 << NumParamsExpr->getSourceRange(); 2306 return; 2307 } 2308 2309 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 2310 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 2311 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 2312 return; 2313 } 2314 2315 d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, 2316 NumParams.getZExtValue())); 2317} 2318 2319static void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){ 2320 if (S.LangOpts.CUDA) { 2321 // check the attribute arguments. 2322 if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 2323 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 2324 << "1 or 2"; 2325 return; 2326 } 2327 2328 if (!isFunctionOrMethod(d)) { 2329 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2330 << Attr.getName() << 0 /*function*/; 2331 return; 2332 } 2333 2334 Expr *MaxThreadsExpr = Attr.getArg(0); 2335 llvm::APSInt MaxThreads(32); 2336 if (MaxThreadsExpr->isTypeDependent() || 2337 MaxThreadsExpr->isValueDependent() || 2338 !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 2339 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 2340 << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 2341 return; 2342 } 2343 2344 llvm::APSInt MinBlocks(32); 2345 if (Attr.getNumArgs() > 1) { 2346 Expr *MinBlocksExpr = Attr.getArg(1); 2347 if (MinBlocksExpr->isTypeDependent() || 2348 MinBlocksExpr->isValueDependent() || 2349 !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 2350 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 2351 << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 2352 return; 2353 } 2354 } 2355 2356 d->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context, 2357 MaxThreads.getZExtValue(), 2358 MinBlocks.getZExtValue())); 2359 } else { 2360 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 2361 } 2362} 2363 2364static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2365 // check the attribute arguments. 2366 if (Attr.getNumArgs() != 0) { 2367 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2368 return; 2369 } 2370 2371 if (!isa<CXXRecordDecl>(d) 2372 && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 2373 S.Diag(Attr.getLoc(), 2374 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2375 : diag::warn_attribute_wrong_decl_type) 2376 << Attr.getName() << 7 /*virtual method or class*/; 2377 return; 2378 } 2379 2380 // FIXME: Conform to C++0x redeclaration rules. 2381 2382 if (d->getAttr<FinalAttr>()) { 2383 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 2384 return; 2385 } 2386 2387 d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context)); 2388} 2389 2390//===----------------------------------------------------------------------===// 2391// C++0x member checking attributes 2392//===----------------------------------------------------------------------===// 2393 2394static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2395 if (Attr.getNumArgs() != 0) { 2396 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2397 return; 2398 } 2399 2400 if (!isa<CXXRecordDecl>(d)) { 2401 S.Diag(Attr.getLoc(), 2402 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2403 : diag::warn_attribute_wrong_decl_type) 2404 << Attr.getName() << 9 /*class*/; 2405 return; 2406 } 2407 2408 if (d->getAttr<BaseCheckAttr>()) { 2409 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 2410 return; 2411 } 2412 2413 d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context)); 2414} 2415 2416static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2417 if (Attr.getNumArgs() != 0) { 2418 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2419 return; 2420 } 2421 2422 if (!isa<RecordDecl>(d->getDeclContext())) { 2423 // FIXME: It's not the type that's the problem 2424 S.Diag(Attr.getLoc(), 2425 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2426 : diag::warn_attribute_wrong_decl_type) 2427 << Attr.getName() << 11 /*member*/; 2428 return; 2429 } 2430 2431 // FIXME: Conform to C++0x redeclaration rules. 2432 2433 if (d->getAttr<HidingAttr>()) { 2434 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 2435 return; 2436 } 2437 2438 d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context)); 2439} 2440 2441static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2442 if (Attr.getNumArgs() != 0) { 2443 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2444 return; 2445 } 2446 2447 if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 2448 // FIXME: It's not the type that's the problem 2449 S.Diag(Attr.getLoc(), 2450 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2451 : diag::warn_attribute_wrong_decl_type) 2452 << Attr.getName() << 10 /*virtual method*/; 2453 return; 2454 } 2455 2456 // FIXME: Conform to C++0x redeclaration rules. 2457 2458 if (d->getAttr<OverrideAttr>()) { 2459 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 2460 return; 2461 } 2462 2463 d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context)); 2464} 2465 2466//===----------------------------------------------------------------------===// 2467// Checker-specific attribute handlers. 2468//===----------------------------------------------------------------------===// 2469 2470static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 2471 Sema &S) { 2472 2473 QualType RetTy; 2474 2475 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 2476 RetTy = MD->getResultType(); 2477 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 2478 RetTy = FD->getResultType(); 2479 else { 2480 SourceLocation L = Attr.getLoc(); 2481 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 2482 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 2483 return; 2484 } 2485 2486 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 2487 || RetTy->getAs<ObjCObjectPointerType>())) { 2488 SourceLocation L = Attr.getLoc(); 2489 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 2490 << SourceRange(L, L) << Attr.getName(); 2491 return; 2492 } 2493 2494 switch (Attr.getKind()) { 2495 default: 2496 assert(0 && "invalid ownership attribute"); 2497 return; 2498 case AttributeList::AT_cf_returns_not_retained: 2499 d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), 2500 S.Context)); 2501 return; 2502 case AttributeList::AT_ns_returns_not_retained: 2503 d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), 2504 S.Context)); 2505 return; 2506 case AttributeList::AT_cf_returns_retained: 2507 d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), 2508 S.Context)); 2509 return; 2510 case AttributeList::AT_ns_returns_retained: 2511 d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), 2512 S.Context)); 2513 return; 2514 }; 2515} 2516 2517static bool isKnownDeclSpecAttr(const AttributeList &Attr) { 2518 return Attr.getKind() == AttributeList::AT_dllimport || 2519 Attr.getKind() == AttributeList::AT_dllexport; 2520} 2521 2522//===----------------------------------------------------------------------===// 2523// Top Level Sema Entry Points 2524//===----------------------------------------------------------------------===// 2525 2526/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 2527/// the attribute applies to decls. If the attribute is a type attribute, just 2528/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 2529/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 2530static void ProcessDeclAttribute(Scope *scope, Decl *D, 2531 const AttributeList &Attr, Sema &S) { 2532 if (Attr.isInvalid()) 2533 return; 2534 2535 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 2536 // FIXME: Try to deal with other __declspec attributes! 2537 return; 2538 switch (Attr.getKind()) { 2539 case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 2540 case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 2541 case AttributeList::AT_IBOutletCollection: 2542 HandleIBOutletCollection(D, Attr, S); break; 2543 case AttributeList::AT_address_space: 2544 case AttributeList::AT_objc_gc: 2545 case AttributeList::AT_vector_size: 2546 case AttributeList::AT_neon_vector_type: 2547 case AttributeList::AT_neon_polyvector_type: 2548 // Ignore these, these are type attributes, handled by 2549 // ProcessTypeAttributes. 2550 break; 2551 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 2552 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 2553 case AttributeList::AT_always_inline: 2554 HandleAlwaysInlineAttr (D, Attr, S); break; 2555 case AttributeList::AT_analyzer_noreturn: 2556 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 2557 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 2558 case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 2559 case AttributeList::AT_carries_dependency: 2560 HandleDependencyAttr (D, Attr, S); break; 2561 case AttributeList::AT_common: HandleCommonAttr (D, Attr, S); break; 2562 case AttributeList::AT_constant: HandleConstantAttr (D, Attr, S); break; 2563 case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 2564 case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 2565 case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 2566 case AttributeList::AT_device: HandleDeviceAttr (D, Attr, S); break; 2567 case AttributeList::AT_ext_vector_type: 2568 HandleExtVectorTypeAttr(scope, D, Attr, S); 2569 break; 2570 case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 2571 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 2572 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 2573 case AttributeList::AT_global: HandleGlobalAttr (D, Attr, S); break; 2574 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 2575 case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 2576 case AttributeList::AT_host: HandleHostAttr (D, Attr, S); break; 2577 case AttributeList::AT_launch_bounds: 2578 HandleLaunchBoundsAttr(D, Attr, S); 2579 break; 2580 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 2581 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 2582 case AttributeList::AT_may_alias: HandleMayAliasAttr (D, Attr, S); break; 2583 case AttributeList::AT_nocommon: HandleNoCommonAttr (D, Attr, S); break; 2584 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 2585 case AttributeList::AT_ownership_returns: 2586 case AttributeList::AT_ownership_takes: 2587 case AttributeList::AT_ownership_holds: 2588 HandleOwnershipAttr (D, Attr, S); break; 2589 case AttributeList::AT_naked: HandleNakedAttr (D, Attr, S); break; 2590 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 2591 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 2592 case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 2593 case AttributeList::AT_shared: HandleSharedAttr (D, Attr, S); break; 2594 case AttributeList::AT_vecreturn: HandleVecReturnAttr (D, Attr, S); break; 2595 2596 // Checker-specific. 2597 case AttributeList::AT_ns_returns_not_retained: 2598 case AttributeList::AT_cf_returns_not_retained: 2599 case AttributeList::AT_ns_returns_retained: 2600 case AttributeList::AT_cf_returns_retained: 2601 HandleNSReturnsRetainedAttr(D, Attr, S); break; 2602 2603 case AttributeList::AT_reqd_wg_size: 2604 HandleReqdWorkGroupSize(D, Attr, S); break; 2605 2606 case AttributeList::AT_init_priority: 2607 HandleInitPriorityAttr(D, Attr, S); break; 2608 2609 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 2610 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 2611 case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 2612 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 2613 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 2614 case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 2615 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 2616 break; 2617 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 2618 case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 2619 case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 2620 case AttributeList::AT_transparent_union: 2621 HandleTransparentUnionAttr(D, Attr, S); 2622 break; 2623 case AttributeList::AT_objc_exception: 2624 HandleObjCExceptionAttr(D, Attr, S); 2625 break; 2626 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 2627 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 2628 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 2629 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 2630 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 2631 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 2632 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 2633 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 2634 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 2635 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 2636 case AttributeList::IgnoredAttribute: 2637 // Just ignore 2638 break; 2639 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 2640 HandleNoInstrumentFunctionAttr(D, Attr, S); 2641 break; 2642 case AttributeList::AT_stdcall: 2643 case AttributeList::AT_cdecl: 2644 case AttributeList::AT_fastcall: 2645 case AttributeList::AT_thiscall: 2646 case AttributeList::AT_pascal: 2647 HandleCallConvAttr(D, Attr, S); 2648 break; 2649 default: 2650 // Ask target about the attribute. 2651 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 2652 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 2653 S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 2654 << Attr.getName(); 2655 break; 2656 } 2657} 2658 2659/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 2660/// attribute list to the specified decl, ignoring any type attributes. 2661void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 2662 const AttributeList *AttrList) { 2663 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 2664 ProcessDeclAttribute(S, D, *l, *this); 2665 } 2666 2667 // GCC accepts 2668 // static int a9 __attribute__((weakref)); 2669 // but that looks really pointless. We reject it. 2670 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 2671 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 2672 dyn_cast<NamedDecl>(D)->getNameAsString(); 2673 return; 2674 } 2675} 2676 2677/// DeclClonePragmaWeak - clone existing decl (maybe definition), 2678/// #pragma weak needs a non-definition decl and source may not have one 2679NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 2680 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 2681 NamedDecl *NewD = 0; 2682 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 2683 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 2684 FD->getLocation(), DeclarationName(II), 2685 FD->getType(), FD->getTypeSourceInfo()); 2686 if (FD->getQualifier()) { 2687 FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 2688 NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 2689 } 2690 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 2691 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 2692 VD->getLocation(), II, 2693 VD->getType(), VD->getTypeSourceInfo(), 2694 VD->getStorageClass(), 2695 VD->getStorageClassAsWritten()); 2696 if (VD->getQualifier()) { 2697 VarDecl *NewVD = cast<VarDecl>(NewD); 2698 NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 2699 } 2700 } 2701 return NewD; 2702} 2703 2704/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 2705/// applied to it, possibly with an alias. 2706void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 2707 if (W.getUsed()) return; // only do this once 2708 W.setUsed(true); 2709 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 2710 IdentifierInfo *NDId = ND->getIdentifier(); 2711 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 2712 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 2713 NDId->getName())); 2714 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2715 WeakTopLevelDecl.push_back(NewD); 2716 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 2717 // to insert Decl at TU scope, sorry. 2718 DeclContext *SavedContext = CurContext; 2719 CurContext = Context.getTranslationUnitDecl(); 2720 PushOnScopeChains(NewD, S); 2721 CurContext = SavedContext; 2722 } else { // just add weak to existing 2723 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2724 } 2725} 2726 2727/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 2728/// it, apply them to D. This is a bit tricky because PD can have attributes 2729/// specified in many different places, and we need to find and apply them all. 2730void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 2731 // It's valid to "forward-declare" #pragma weak, in which case we 2732 // have to do this. 2733 if (!WeakUndeclaredIdentifiers.empty()) { 2734 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 2735 if (IdentifierInfo *Id = ND->getIdentifier()) { 2736 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 2737 = WeakUndeclaredIdentifiers.find(Id); 2738 if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 2739 WeakInfo W = I->second; 2740 DeclApplyPragmaWeak(S, ND, W); 2741 WeakUndeclaredIdentifiers[Id] = W; 2742 } 2743 } 2744 } 2745 } 2746 2747 // Apply decl attributes from the DeclSpec if present. 2748 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 2749 ProcessDeclAttributeList(S, D, Attrs); 2750 2751 // Walk the declarator structure, applying decl attributes that were in a type 2752 // position to the decl itself. This handles cases like: 2753 // int *__attr__(x)** D; 2754 // when X is a decl attribute. 2755 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 2756 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 2757 ProcessDeclAttributeList(S, D, Attrs); 2758 2759 // Finally, apply any attributes on the decl itself. 2760 if (const AttributeList *Attrs = PD.getAttributes()) 2761 ProcessDeclAttributeList(S, D, Attrs); 2762} 2763 2764/// PushParsingDeclaration - Enter a new "scope" of deprecation 2765/// warnings. 2766/// 2767/// The state token we use is the start index of this scope 2768/// on the warning stack. 2769Sema::ParsingDeclStackState Sema::PushParsingDeclaration() { 2770 ParsingDeclDepth++; 2771 return (ParsingDeclStackState) DelayedDiagnostics.size(); 2772} 2773 2774void Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) { 2775 assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 2776 ParsingDeclDepth--; 2777 2778 if (DelayedDiagnostics.empty()) 2779 return; 2780 2781 unsigned SavedIndex = (unsigned) S; 2782 assert(SavedIndex <= DelayedDiagnostics.size() && 2783 "saved index is out of bounds"); 2784 2785 unsigned E = DelayedDiagnostics.size(); 2786 2787 // We only want to actually emit delayed diagnostics when we 2788 // successfully parsed a decl. 2789 if (D) { 2790 // We really do want to start with 0 here. We get one push for a 2791 // decl spec and another for each declarator; in a decl group like: 2792 // deprecated_typedef foo, *bar, baz(); 2793 // only the declarator pops will be passed decls. This is correct; 2794 // we really do need to consider delayed diagnostics from the decl spec 2795 // for each of the different declarations. 2796 for (unsigned I = 0; I != E; ++I) { 2797 if (DelayedDiagnostics[I].Triggered) 2798 continue; 2799 2800 switch (DelayedDiagnostics[I].Kind) { 2801 case DelayedDiagnostic::Deprecation: 2802 HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 2803 break; 2804 2805 case DelayedDiagnostic::Access: 2806 HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 2807 break; 2808 } 2809 } 2810 } 2811 2812 // Destroy all the delayed diagnostics we're about to pop off. 2813 for (unsigned I = SavedIndex; I != E; ++I) 2814 DelayedDiagnostics[I].destroy(); 2815 2816 DelayedDiagnostics.set_size(SavedIndex); 2817} 2818 2819static bool isDeclDeprecated(Decl *D) { 2820 do { 2821 if (D->hasAttr<DeprecatedAttr>()) 2822 return true; 2823 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 2824 return false; 2825} 2826 2827void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 2828 Decl *Ctx) { 2829 if (isDeclDeprecated(Ctx)) 2830 return; 2831 2832 DD.Triggered = true; 2833 if (!DD.getDeprecationMessage().empty()) 2834 Diag(DD.Loc, diag::warn_deprecated_message) 2835 << DD.getDeprecationDecl()->getDeclName() 2836 << DD.getDeprecationMessage(); 2837 else 2838 Diag(DD.Loc, diag::warn_deprecated) 2839 << DD.getDeprecationDecl()->getDeclName(); 2840} 2841 2842void Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message, 2843 SourceLocation Loc) { 2844 // Delay if we're currently parsing a declaration. 2845 if (ParsingDeclDepth) { 2846 DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D, 2847 Message)); 2848 return; 2849 } 2850 2851 // Otherwise, don't warn if our current context is deprecated. 2852 if (isDeclDeprecated(cast<Decl>(CurContext))) 2853 return; 2854 if (!Message.empty()) 2855 Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 2856 << Message; 2857 else 2858 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 2859} 2860