SemaDeclAttr.cpp revision 3a387441ae339363ee5b254658f295e97bd9e913
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/DeclTemplate.h" 19#include "clang/AST/DeclObjC.h" 20#include "clang/AST/Expr.h" 21#include "clang/Basic/SourceManager.h" 22#include "clang/Basic/TargetInfo.h" 23#include "clang/Sema/DeclSpec.h" 24#include "clang/Sema/DelayedDiagnostic.h" 25#include "clang/Sema/Lookup.h" 26#include "llvm/ADT/StringExtras.h" 27using namespace clang; 28using namespace sema; 29 30/// These constants match the enumerated choices of 31/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 32enum AttributeDeclKind { 33 ExpectedFunction, 34 ExpectedUnion, 35 ExpectedVariableOrFunction, 36 ExpectedFunctionOrMethod, 37 ExpectedParameter, 38 ExpectedParameterOrMethod, 39 ExpectedFunctionMethodOrBlock, 40 ExpectedClassOrVirtualMethod, 41 ExpectedFunctionMethodOrParameter, 42 ExpectedClass, 43 ExpectedVirtualMethod, 44 ExpectedClassMember, 45 ExpectedVariable, 46 ExpectedMethod, 47 ExpectedVariableFunctionOrLabel, 48 ExpectedFieldOrGlobalVar 49}; 50 51//===----------------------------------------------------------------------===// 52// Helper functions 53//===----------------------------------------------------------------------===// 54 55static const FunctionType *getFunctionType(const Decl *D, 56 bool blocksToo = true) { 57 QualType Ty; 58 if (const ValueDecl *decl = dyn_cast<ValueDecl>(D)) 59 Ty = decl->getType(); 60 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D)) 61 Ty = decl->getType(); 62 else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D)) 63 Ty = decl->getUnderlyingType(); 64 else 65 return 0; 66 67 if (Ty->isFunctionPointerType()) 68 Ty = Ty->getAs<PointerType>()->getPointeeType(); 69 else if (blocksToo && Ty->isBlockPointerType()) 70 Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 71 72 return Ty->getAs<FunctionType>(); 73} 74 75// FIXME: We should provide an abstraction around a method or function 76// to provide the following bits of information. 77 78/// isFunction - Return true if the given decl has function 79/// type (function or function-typed variable). 80static bool isFunction(const Decl *D) { 81 return getFunctionType(D, false) != NULL; 82} 83 84/// isFunctionOrMethod - Return true if the given decl has function 85/// type (function or function-typed variable) or an Objective-C 86/// method. 87static bool isFunctionOrMethod(const Decl *D) { 88 return isFunction(D)|| isa<ObjCMethodDecl>(D); 89} 90 91/// isFunctionOrMethodOrBlock - Return true if the given decl has function 92/// type (function or function-typed variable) or an Objective-C 93/// method or a block. 94static bool isFunctionOrMethodOrBlock(const Decl *D) { 95 if (isFunctionOrMethod(D)) 96 return true; 97 // check for block is more involved. 98 if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 99 QualType Ty = V->getType(); 100 return Ty->isBlockPointerType(); 101 } 102 return isa<BlockDecl>(D); 103} 104 105/// Return true if the given decl has a declarator that should have 106/// been processed by Sema::GetTypeForDeclarator. 107static bool hasDeclarator(const Decl *D) { 108 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. 109 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) || 110 isa<ObjCPropertyDecl>(D); 111} 112 113/// hasFunctionProto - Return true if the given decl has a argument 114/// information. This decl should have already passed 115/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 116static bool hasFunctionProto(const Decl *D) { 117 if (const FunctionType *FnTy = getFunctionType(D)) 118 return isa<FunctionProtoType>(FnTy); 119 else { 120 assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D)); 121 return true; 122 } 123} 124 125/// getFunctionOrMethodNumArgs - Return number of function or method 126/// arguments. It is an error to call this on a K&R function (use 127/// hasFunctionProto first). 128static unsigned getFunctionOrMethodNumArgs(const Decl *D) { 129 if (const FunctionType *FnTy = getFunctionType(D)) 130 return cast<FunctionProtoType>(FnTy)->getNumArgs(); 131 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 132 return BD->getNumParams(); 133 return cast<ObjCMethodDecl>(D)->param_size(); 134} 135 136static QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) { 137 if (const FunctionType *FnTy = getFunctionType(D)) 138 return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 139 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 140 return BD->getParamDecl(Idx)->getType(); 141 142 return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType(); 143} 144 145static QualType getFunctionOrMethodResultType(const Decl *D) { 146 if (const FunctionType *FnTy = getFunctionType(D)) 147 return cast<FunctionProtoType>(FnTy)->getResultType(); 148 return cast<ObjCMethodDecl>(D)->getResultType(); 149} 150 151static bool isFunctionOrMethodVariadic(const Decl *D) { 152 if (const FunctionType *FnTy = getFunctionType(D)) { 153 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 154 return proto->isVariadic(); 155 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 156 return BD->isVariadic(); 157 else { 158 return cast<ObjCMethodDecl>(D)->isVariadic(); 159 } 160} 161 162static bool isInstanceMethod(const Decl *D) { 163 if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) 164 return MethodDecl->isInstance(); 165 return false; 166} 167 168static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 169 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 170 if (!PT) 171 return false; 172 173 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 174 if (!Cls) 175 return false; 176 177 IdentifierInfo* ClsName = Cls->getIdentifier(); 178 179 // FIXME: Should we walk the chain of classes? 180 return ClsName == &Ctx.Idents.get("NSString") || 181 ClsName == &Ctx.Idents.get("NSMutableString"); 182} 183 184static inline bool isCFStringType(QualType T, ASTContext &Ctx) { 185 const PointerType *PT = T->getAs<PointerType>(); 186 if (!PT) 187 return false; 188 189 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 190 if (!RT) 191 return false; 192 193 const RecordDecl *RD = RT->getDecl(); 194 if (RD->getTagKind() != TTK_Struct) 195 return false; 196 197 return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 198} 199 200/// \brief Check if the attribute has exactly as many args as Num. May 201/// output an error. 202static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, 203 unsigned int Num) { 204 if (Attr.getNumArgs() != Num) { 205 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num; 206 return false; 207 } 208 209 return true; 210} 211 212 213/// \brief Check if the attribute has at least as many args as Num. May 214/// output an error. 215static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr, 216 unsigned int Num) { 217 if (Attr.getNumArgs() < Num) { 218 S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num; 219 return false; 220 } 221 222 return true; 223} 224 225/// 226/// \brief Check if passed in Decl is a field or potentially shared global var 227/// \return true if the Decl is a field or potentially shared global variable 228/// 229static bool mayBeSharedVariable(const Decl *D) { 230 if (isa<FieldDecl>(D)) 231 return true; 232 if (const VarDecl *vd = dyn_cast<VarDecl>(D)) 233 return (vd->hasGlobalStorage() && !(vd->isThreadSpecified())); 234 235 return false; 236} 237 238/// \brief Check if the passed-in expression is of type int or bool. 239static bool isIntOrBool(Expr *Exp) { 240 QualType QT = Exp->getType(); 241 return QT->isBooleanType() || QT->isIntegerType(); 242} 243 244/// 245/// \brief Check if passed in Decl is a pointer type. 246/// Note that this function may produce an error message. 247/// \return true if the Decl is a pointer type; false otherwise 248/// 249static bool checkIsPointer(Sema &S, const Decl *D, const AttributeList &Attr) { 250 if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) { 251 QualType QT = vd->getType(); 252 if (QT->isAnyPointerType()) 253 return true; 254 S.Diag(Attr.getLoc(), diag::warn_pointer_attribute_wrong_type) 255 << Attr.getName()->getName() << QT; 256 } else { 257 S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl) 258 << Attr.getName(); 259 } 260 return false; 261} 262 263/// \brief Checks that the passed in QualType either is of RecordType or points 264/// to RecordType. Returns the relevant RecordType, null if it does not exit. 265static const RecordType *getRecordType(QualType QT) { 266 if (const RecordType *RT = QT->getAs<RecordType>()) 267 return RT; 268 269 // Now check if we point to record type. 270 if (const PointerType *PT = QT->getAs<PointerType>()) 271 return PT->getPointeeType()->getAs<RecordType>(); 272 273 return 0; 274} 275 276/// \brief Thread Safety Analysis: Checks that the passed in RecordType 277/// resolves to a lockable object. May flag an error. 278static bool checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, 279 const RecordType *RT) { 280 // Flag error if could not get record type for this argument. 281 if (!RT) { 282 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_class) 283 << Attr.getName(); 284 return false; 285 } 286 // Flag error if the type is not lockable. 287 if (!RT->getDecl()->getAttr<LockableAttr>()) { 288 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_lockable) 289 << Attr.getName(); 290 return false; 291 } 292 return true; 293} 294 295/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting 296/// from Sidx, resolve to a lockable object. May flag an error. 297/// \param Sidx The attribute argument index to start checking with. 298/// \param ParamIdxOk Whether an argument can be indexing into a function 299/// parameter list. 300static bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D, 301 const AttributeList &Attr, 302 SmallVectorImpl<Expr*> &Args, 303 int Sidx = 0, 304 bool ParamIdxOk = false) { 305 for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { 306 Expr *ArgExp = Attr.getArg(Idx); 307 308 if (ArgExp->isTypeDependent()) { 309 // FIXME -- need to processs this again on template instantiation 310 Args.push_back(ArgExp); 311 continue; 312 } 313 314 QualType ArgTy = ArgExp->getType(); 315 316 // First see if we can just cast to record type, or point to record type. 317 const RecordType *RT = getRecordType(ArgTy); 318 319 // Now check if we index into a record type function param. 320 if(!RT && ParamIdxOk) { 321 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 322 IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); 323 if(FD && IL) { 324 unsigned int NumParams = FD->getNumParams(); 325 llvm::APInt ArgValue = IL->getValue(); 326 uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); 327 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; 328 if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { 329 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range) 330 << Attr.getName() << Idx + 1 << NumParams; 331 return false; 332 } 333 ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); 334 RT = getRecordType(ArgTy); 335 } 336 } 337 338 if (!checkForLockableRecord(S, D, Attr, RT)) 339 return false; 340 341 Args.push_back(ArgExp); 342 } 343 return true; 344} 345 346//===----------------------------------------------------------------------===// 347// Attribute Implementations 348//===----------------------------------------------------------------------===// 349 350// FIXME: All this manual attribute parsing code is gross. At the 351// least add some helper functions to check most argument patterns (# 352// and types of args). 353 354static void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr, 355 bool pointer = false) { 356 assert(!Attr.isInvalid()); 357 358 if (!checkAttributeNumArgs(S, Attr, 0)) 359 return; 360 361 // D must be either a member field or global (potentially shared) variable. 362 if (!mayBeSharedVariable(D)) { 363 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 364 << Attr.getName() << ExpectedFieldOrGlobalVar; 365 return; 366 } 367 368 if (pointer && !checkIsPointer(S, D, Attr)) 369 return; 370 371 if (pointer) 372 D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context)); 373 else 374 D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context)); 375} 376 377static void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr, 378 bool pointer = false) { 379 assert(!Attr.isInvalid()); 380 381 if (!checkAttributeNumArgs(S, Attr, 1)) 382 return; 383 384 Expr *Arg = Attr.getArg(0); 385 386 // D must be either a member field or global (potentially shared) variable. 387 if (!mayBeSharedVariable(D)) { 388 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 389 << Attr.getName() << ExpectedFieldOrGlobalVar; 390 return; 391 } 392 393 if (pointer && !checkIsPointer(S, D, Attr)) 394 return; 395 396 if (Arg->isTypeDependent()) 397 // FIXME: handle attributes with dependent types 398 return; 399 400 // check that the argument is lockable object 401 if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType()))) 402 return; 403 404 if (pointer) 405 D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(), 406 S.Context, Arg)); 407 else 408 D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg)); 409} 410 411 412static void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr, 413 bool scoped = false) { 414 assert(!Attr.isInvalid()); 415 416 if (!checkAttributeNumArgs(S, Attr, 0)) 417 return; 418 419 // FIXME: Lockable structs for C code. 420 if (!isa<CXXRecordDecl>(D)) { 421 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 422 << Attr.getName() << ExpectedClass; 423 return; 424 } 425 426 if (scoped) 427 D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context)); 428 else 429 D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context)); 430} 431 432static void handleNoThreadSafetyAttr(Sema &S, Decl *D, 433 const AttributeList &Attr) { 434 assert(!Attr.isInvalid()); 435 436 if (!checkAttributeNumArgs(S, Attr, 0)) 437 return; 438 439 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 440 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 441 << Attr.getName() << ExpectedFunctionOrMethod; 442 return; 443 } 444 445 D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(), 446 S.Context)); 447} 448 449static void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr, 450 bool before) { 451 assert(!Attr.isInvalid()); 452 453 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 454 return; 455 456 // D must be either a member field or global (potentially shared) variable. 457 ValueDecl *VD = dyn_cast<ValueDecl>(D); 458 if (!VD || !mayBeSharedVariable(D)) { 459 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 460 << Attr.getName() << ExpectedFieldOrGlobalVar; 461 return; 462 } 463 464 // Check that this attribute only applies to lockable types 465 QualType QT = VD->getType(); 466 if (!QT->isDependentType()) { 467 const RecordType *RT = getRecordType(QT); 468 if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) { 469 S.Diag(Attr.getLoc(), diag::err_attribute_decl_not_lockable) 470 << Attr.getName(); 471 return; 472 } 473 } 474 475 SmallVector<Expr*, 1> Args; 476 // check that all arguments are lockable objects 477 if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args)) 478 return; 479 480 unsigned Size = Args.size(); 481 assert(Size == Attr.getNumArgs()); 482 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 483 484 if (before) 485 D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context, 486 StartArg, Size)); 487 else 488 D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context, 489 StartArg, Size)); 490} 491 492static void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 493 bool exclusive = false) { 494 assert(!Attr.isInvalid()); 495 496 // zero or more arguments ok 497 498 // check that the attribute is applied to a function 499 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 500 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 501 << Attr.getName() << ExpectedFunctionOrMethod; 502 return; 503 } 504 505 // check that all arguments are lockable objects 506 SmallVector<Expr*, 1> Args; 507 if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true)) 508 return; 509 510 unsigned Size = Args.size(); 511 assert(Size == Attr.getNumArgs()); 512 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 513 514 if (exclusive) 515 D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(), 516 S.Context, StartArg, 517 Size)); 518 else 519 D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(), 520 S.Context, StartArg, 521 Size)); 522} 523 524static void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 525 bool exclusive = false) { 526 assert(!Attr.isInvalid()); 527 528 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 529 return; 530 531 532 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 533 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 534 << Attr.getName() << ExpectedFunctionOrMethod; 535 return; 536 } 537 538 if (!isIntOrBool(Attr.getArg(0))) { 539 S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool) 540 << Attr.getName(); 541 return; 542 } 543 544 SmallVector<Expr*, 2> Args; 545 // check that all arguments are lockable objects 546 if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1)) 547 return; 548 549 unsigned Size = Args.size(); 550 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 551 552 if (exclusive) 553 D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(), 554 S.Context, 555 Attr.getArg(0), 556 StartArg, Size)); 557 else 558 D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(), 559 S.Context, 560 Attr.getArg(0), 561 StartArg, Size)); 562} 563 564static void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr, 565 bool exclusive = false) { 566 assert(!Attr.isInvalid()); 567 568 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 569 return; 570 571 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 572 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 573 << Attr.getName() << ExpectedFunctionOrMethod; 574 return; 575 } 576 577 // check that all arguments are lockable objects 578 SmallVector<Expr*, 1> Args; 579 if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args)) 580 return; 581 582 unsigned Size = Args.size(); 583 assert(Size == Attr.getNumArgs()); 584 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 585 586 if (exclusive) 587 D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(), 588 S.Context, StartArg, 589 Size)); 590 else 591 D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(), 592 S.Context, StartArg, 593 Size)); 594} 595 596static void handleUnlockFunAttr(Sema &S, Decl *D, 597 const AttributeList &Attr) { 598 assert(!Attr.isInvalid()); 599 600 // zero or more arguments ok 601 602 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 603 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 604 << Attr.getName() << ExpectedFunctionOrMethod; 605 return; 606 } 607 608 // check that all arguments are lockable objects 609 SmallVector<Expr*, 1> Args; 610 if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true)) 611 return; 612 613 unsigned Size = Args.size(); 614 assert(Size == Attr.getNumArgs()); 615 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 616 617 D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context, 618 StartArg, Size)); 619} 620 621static void handleLockReturnedAttr(Sema &S, Decl *D, 622 const AttributeList &Attr) { 623 assert(!Attr.isInvalid()); 624 625 if (!checkAttributeNumArgs(S, Attr, 1)) 626 return; 627 Expr *Arg = Attr.getArg(0); 628 629 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 630 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 631 << Attr.getName() << ExpectedFunctionOrMethod; 632 return; 633 } 634 635 if (Arg->isTypeDependent()) 636 return; 637 638 // check that the argument is lockable object 639 if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType()))) 640 return; 641 642 D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg)); 643} 644 645static void handleLocksExcludedAttr(Sema &S, Decl *D, 646 const AttributeList &Attr) { 647 assert(!Attr.isInvalid()); 648 649 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 650 return; 651 652 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 653 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 654 << Attr.getName() << ExpectedFunctionOrMethod; 655 return; 656 } 657 658 // check that all arguments are lockable objects 659 SmallVector<Expr*, 1> Args; 660 if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args)) 661 return; 662 663 unsigned Size = Args.size(); 664 assert(Size == Attr.getNumArgs()); 665 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 666 667 D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context, 668 StartArg, Size)); 669} 670 671 672static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, 673 const AttributeList &Attr) { 674 TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D); 675 if (tDecl == 0) { 676 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 677 return; 678 } 679 680 QualType curType = tDecl->getUnderlyingType(); 681 682 Expr *sizeExpr; 683 684 // Special case where the argument is a template id. 685 if (Attr.getParameterName()) { 686 CXXScopeSpec SS; 687 UnqualifiedId id; 688 id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 689 690 ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false); 691 if (Size.isInvalid()) 692 return; 693 694 sizeExpr = Size.get(); 695 } else { 696 // check the attribute arguments. 697 if (!checkAttributeNumArgs(S, Attr, 1)) 698 return; 699 700 sizeExpr = Attr.getArg(0); 701 } 702 703 // Instantiate/Install the vector type, and let Sema build the type for us. 704 // This will run the reguired checks. 705 QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 706 if (!T.isNull()) { 707 // FIXME: preserve the old source info. 708 tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 709 710 // Remember this typedef decl, we will need it later for diagnostics. 711 S.ExtVectorDecls.push_back(tDecl); 712 } 713} 714 715static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 716 // check the attribute arguments. 717 if (!checkAttributeNumArgs(S, Attr, 0)) 718 return; 719 720 if (TagDecl *TD = dyn_cast<TagDecl>(D)) 721 TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 722 else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 723 // If the alignment is less than or equal to 8 bits, the packed attribute 724 // has no effect. 725 if (!FD->getType()->isIncompleteType() && 726 S.Context.getTypeAlign(FD->getType()) <= 8) 727 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 728 << Attr.getName() << FD->getType(); 729 else 730 FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 731 } else 732 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 733} 734 735static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) { 736 if (TagDecl *TD = dyn_cast<TagDecl>(D)) 737 TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context)); 738 else 739 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 740} 741 742static void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) { 743 // check the attribute arguments. 744 if (!checkAttributeNumArgs(S, Attr, 0)) 745 return; 746 747 // The IBAction attributes only apply to instance methods. 748 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 749 if (MD->isInstanceMethod()) { 750 D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context)); 751 return; 752 } 753 754 S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName(); 755} 756 757static bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) { 758 // The IBOutlet/IBOutletCollection attributes only apply to instance 759 // variables or properties of Objective-C classes. The outlet must also 760 // have an object reference type. 761 if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) { 762 if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 763 S.Diag(Attr.getLoc(), diag::err_iboutlet_object_type) 764 << Attr.getName() << VD->getType() << 0; 765 return false; 766 } 767 } 768 else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 769 if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 770 S.Diag(Attr.getLoc(), diag::err_iboutlet_object_type) 771 << Attr.getName() << PD->getType() << 1; 772 return false; 773 } 774 } 775 else { 776 S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 777 return false; 778 } 779 780 return true; 781} 782 783static void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) { 784 // check the attribute arguments. 785 if (!checkAttributeNumArgs(S, Attr, 0)) 786 return; 787 788 if (!checkIBOutletCommon(S, D, Attr)) 789 return; 790 791 D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context)); 792} 793 794static void handleIBOutletCollection(Sema &S, Decl *D, 795 const AttributeList &Attr) { 796 797 // The iboutletcollection attribute can have zero or one arguments. 798 if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 799 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 800 return; 801 } 802 803 if (!checkIBOutletCommon(S, D, Attr)) 804 return; 805 806 IdentifierInfo *II = Attr.getParameterName(); 807 if (!II) 808 II = &S.Context.Idents.get("id"); 809 810 ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 811 S.getScopeForContext(D->getDeclContext()->getParent())); 812 if (!TypeRep) { 813 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 814 return; 815 } 816 QualType QT = TypeRep.get(); 817 // Diagnose use of non-object type in iboutletcollection attribute. 818 // FIXME. Gnu attribute extension ignores use of builtin types in 819 // attributes. So, __attribute__((iboutletcollection(char))) will be 820 // treated as __attribute__((iboutletcollection())). 821 if (!QT->isObjCIdType() && !QT->isObjCClassType() && 822 !QT->isObjCObjectType()) { 823 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 824 return; 825 } 826 D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context, 827 QT, Attr.getParameterLoc())); 828} 829 830static void possibleTransparentUnionPointerType(QualType &T) { 831 if (const RecordType *UT = T->getAsUnionType()) 832 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 833 RecordDecl *UD = UT->getDecl(); 834 for (RecordDecl::field_iterator it = UD->field_begin(), 835 itend = UD->field_end(); it != itend; ++it) { 836 QualType QT = it->getType(); 837 if (QT->isAnyPointerType() || QT->isBlockPointerType()) { 838 T = QT; 839 return; 840 } 841 } 842 } 843} 844 845static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { 846 // GCC ignores the nonnull attribute on K&R style function prototypes, so we 847 // ignore it as well 848 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 849 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 850 << Attr.getName() << ExpectedFunction; 851 return; 852 } 853 854 // In C++ the implicit 'this' function parameter also counts, and they are 855 // counted from one. 856 bool HasImplicitThisParam = isInstanceMethod(D); 857 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 858 859 // The nonnull attribute only applies to pointers. 860 SmallVector<unsigned, 10> NonNullArgs; 861 862 for (AttributeList::arg_iterator I=Attr.arg_begin(), 863 E=Attr.arg_end(); I!=E; ++I) { 864 865 866 // The argument must be an integer constant expression. 867 Expr *Ex = *I; 868 llvm::APSInt ArgNum(32); 869 if (Ex->isTypeDependent() || Ex->isValueDependent() || 870 !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 871 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 872 << "nonnull" << Ex->getSourceRange(); 873 return; 874 } 875 876 unsigned x = (unsigned) ArgNum.getZExtValue(); 877 878 if (x < 1 || x > NumArgs) { 879 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 880 << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 881 return; 882 } 883 884 --x; 885 if (HasImplicitThisParam) { 886 if (x == 0) { 887 S.Diag(Attr.getLoc(), 888 diag::err_attribute_invalid_implicit_this_argument) 889 << "nonnull" << Ex->getSourceRange(); 890 return; 891 } 892 --x; 893 } 894 895 // Is the function argument a pointer type? 896 QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType(); 897 possibleTransparentUnionPointerType(T); 898 899 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 900 // FIXME: Should also highlight argument in decl. 901 S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 902 << "nonnull" << Ex->getSourceRange(); 903 continue; 904 } 905 906 NonNullArgs.push_back(x); 907 } 908 909 // If no arguments were specified to __attribute__((nonnull)) then all pointer 910 // arguments have a nonnull attribute. 911 if (NonNullArgs.empty()) { 912 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) { 913 QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType(); 914 possibleTransparentUnionPointerType(T); 915 if (T->isAnyPointerType() || T->isBlockPointerType()) 916 NonNullArgs.push_back(I); 917 } 918 919 // No pointer arguments? 920 if (NonNullArgs.empty()) { 921 // Warn the trivial case only if attribute is not coming from a 922 // macro instantiation. 923 if (Attr.getLoc().isFileID()) 924 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 925 return; 926 } 927 } 928 929 unsigned* start = &NonNullArgs[0]; 930 unsigned size = NonNullArgs.size(); 931 llvm::array_pod_sort(start, start + size); 932 D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start, 933 size)); 934} 935 936static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { 937 // This attribute must be applied to a function declaration. 938 // The first argument to the attribute must be a string, 939 // the name of the resource, for example "malloc". 940 // The following arguments must be argument indexes, the arguments must be 941 // of integer type for Returns, otherwise of pointer type. 942 // The difference between Holds and Takes is that a pointer may still be used 943 // after being held. free() should be __attribute((ownership_takes)), whereas 944 // a list append function may well be __attribute((ownership_holds)). 945 946 if (!AL.getParameterName()) { 947 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 948 << AL.getName()->getName() << 1; 949 return; 950 } 951 // Figure out our Kind, and check arguments while we're at it. 952 OwnershipAttr::OwnershipKind K; 953 switch (AL.getKind()) { 954 case AttributeList::AT_ownership_takes: 955 K = OwnershipAttr::Takes; 956 if (AL.getNumArgs() < 1) { 957 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 958 return; 959 } 960 break; 961 case AttributeList::AT_ownership_holds: 962 K = OwnershipAttr::Holds; 963 if (AL.getNumArgs() < 1) { 964 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 965 return; 966 } 967 break; 968 case AttributeList::AT_ownership_returns: 969 K = OwnershipAttr::Returns; 970 if (AL.getNumArgs() > 1) { 971 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 972 << AL.getNumArgs() + 1; 973 return; 974 } 975 break; 976 default: 977 // This should never happen given how we are called. 978 llvm_unreachable("Unknown ownership attribute"); 979 } 980 981 if (!isFunction(D) || !hasFunctionProto(D)) { 982 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) 983 << AL.getName() << ExpectedFunction; 984 return; 985 } 986 987 // In C++ the implicit 'this' function parameter also counts, and they are 988 // counted from one. 989 bool HasImplicitThisParam = isInstanceMethod(D); 990 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 991 992 StringRef Module = AL.getParameterName()->getName(); 993 994 // Normalize the argument, __foo__ becomes foo. 995 if (Module.startswith("__") && Module.endswith("__")) 996 Module = Module.substr(2, Module.size() - 4); 997 998 SmallVector<unsigned, 10> OwnershipArgs; 999 1000 for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 1001 ++I) { 1002 1003 Expr *IdxExpr = *I; 1004 llvm::APSInt ArgNum(32); 1005 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1006 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1007 S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 1008 << AL.getName()->getName() << IdxExpr->getSourceRange(); 1009 continue; 1010 } 1011 1012 unsigned x = (unsigned) ArgNum.getZExtValue(); 1013 1014 if (x > NumArgs || x < 1) { 1015 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 1016 << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 1017 continue; 1018 } 1019 --x; 1020 if (HasImplicitThisParam) { 1021 if (x == 0) { 1022 S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 1023 << "ownership" << IdxExpr->getSourceRange(); 1024 return; 1025 } 1026 --x; 1027 } 1028 1029 switch (K) { 1030 case OwnershipAttr::Takes: 1031 case OwnershipAttr::Holds: { 1032 // Is the function argument a pointer type? 1033 QualType T = getFunctionOrMethodArgType(D, x); 1034 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 1035 // FIXME: Should also highlight argument in decl. 1036 S.Diag(AL.getLoc(), diag::err_ownership_type) 1037 << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 1038 << "pointer" 1039 << IdxExpr->getSourceRange(); 1040 continue; 1041 } 1042 break; 1043 } 1044 case OwnershipAttr::Returns: { 1045 if (AL.getNumArgs() > 1) { 1046 // Is the function argument an integer type? 1047 Expr *IdxExpr = AL.getArg(0); 1048 llvm::APSInt ArgNum(32); 1049 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1050 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1051 S.Diag(AL.getLoc(), diag::err_ownership_type) 1052 << "ownership_returns" << "integer" 1053 << IdxExpr->getSourceRange(); 1054 return; 1055 } 1056 } 1057 break; 1058 } 1059 default: 1060 llvm_unreachable("Unknown ownership attribute"); 1061 } // switch 1062 1063 // Check we don't have a conflict with another ownership attribute. 1064 for (specific_attr_iterator<OwnershipAttr> 1065 i = D->specific_attr_begin<OwnershipAttr>(), 1066 e = D->specific_attr_end<OwnershipAttr>(); 1067 i != e; ++i) { 1068 if ((*i)->getOwnKind() != K) { 1069 for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 1070 I!=E; ++I) { 1071 if (x == *I) { 1072 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 1073 << AL.getName()->getName() << "ownership_*"; 1074 } 1075 } 1076 } 1077 } 1078 OwnershipArgs.push_back(x); 1079 } 1080 1081 unsigned* start = OwnershipArgs.data(); 1082 unsigned size = OwnershipArgs.size(); 1083 llvm::array_pod_sort(start, start + size); 1084 1085 if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 1086 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 1087 return; 1088 } 1089 1090 D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 1091 start, size)); 1092} 1093 1094/// Whether this declaration has internal linkage for the purposes of 1095/// things that want to complain about things not have internal linkage. 1096static bool hasEffectivelyInternalLinkage(NamedDecl *D) { 1097 switch (D->getLinkage()) { 1098 case NoLinkage: 1099 case InternalLinkage: 1100 return true; 1101 1102 // Template instantiations that go from external to unique-external 1103 // shouldn't get diagnosed. 1104 case UniqueExternalLinkage: 1105 return true; 1106 1107 case ExternalLinkage: 1108 return false; 1109 } 1110 llvm_unreachable("unknown linkage kind!"); 1111 return false; 1112} 1113 1114static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1115 // Check the attribute arguments. 1116 if (Attr.getNumArgs() > 1) { 1117 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1118 return; 1119 } 1120 1121 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 1122 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1123 << Attr.getName() << ExpectedVariableOrFunction; 1124 return; 1125 } 1126 1127 NamedDecl *nd = cast<NamedDecl>(D); 1128 1129 // gcc rejects 1130 // class c { 1131 // static int a __attribute__((weakref ("v2"))); 1132 // static int b() __attribute__((weakref ("f3"))); 1133 // }; 1134 // and ignores the attributes of 1135 // void f(void) { 1136 // static int a __attribute__((weakref ("v2"))); 1137 // } 1138 // we reject them 1139 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); 1140 if (!Ctx->isFileContext()) { 1141 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 1142 nd->getNameAsString(); 1143 return; 1144 } 1145 1146 // The GCC manual says 1147 // 1148 // At present, a declaration to which `weakref' is attached can only 1149 // be `static'. 1150 // 1151 // It also says 1152 // 1153 // Without a TARGET, 1154 // given as an argument to `weakref' or to `alias', `weakref' is 1155 // equivalent to `weak'. 1156 // 1157 // gcc 4.4.1 will accept 1158 // int a7 __attribute__((weakref)); 1159 // as 1160 // int a7 __attribute__((weak)); 1161 // This looks like a bug in gcc. We reject that for now. We should revisit 1162 // it if this behaviour is actually used. 1163 1164 if (!hasEffectivelyInternalLinkage(nd)) { 1165 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static); 1166 return; 1167 } 1168 1169 // GCC rejects 1170 // static ((alias ("y"), weakref)). 1171 // Should we? How to check that weakref is before or after alias? 1172 1173 if (Attr.getNumArgs() == 1) { 1174 Expr *Arg = Attr.getArg(0); 1175 Arg = Arg->IgnoreParenCasts(); 1176 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1177 1178 if (!Str || !Str->isAscii()) { 1179 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1180 << "weakref" << 1; 1181 return; 1182 } 1183 // GCC will accept anything as the argument of weakref. Should we 1184 // check for an existing decl? 1185 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1186 Str->getString())); 1187 } 1188 1189 D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context)); 1190} 1191 1192static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1193 // check the attribute arguments. 1194 if (Attr.getNumArgs() != 1) { 1195 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1196 return; 1197 } 1198 1199 Expr *Arg = Attr.getArg(0); 1200 Arg = Arg->IgnoreParenCasts(); 1201 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1202 1203 if (!Str || !Str->isAscii()) { 1204 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1205 << "alias" << 1; 1206 return; 1207 } 1208 1209 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { 1210 S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 1211 return; 1212 } 1213 1214 // FIXME: check if target symbol exists in current file 1215 1216 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1217 Str->getString())); 1218} 1219 1220static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1221 // Check the attribute arguments. 1222 if (!checkAttributeNumArgs(S, Attr, 0)) 1223 return; 1224 1225 if (!isa<FunctionDecl>(D)) { 1226 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1227 << Attr.getName() << ExpectedFunction; 1228 return; 1229 } 1230 1231 D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context)); 1232} 1233 1234static void handleAlwaysInlineAttr(Sema &S, Decl *D, 1235 const AttributeList &Attr) { 1236 // Check the attribute arguments. 1237 if (Attr.hasParameterOrArguments()) { 1238 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1239 return; 1240 } 1241 1242 if (!isa<FunctionDecl>(D)) { 1243 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1244 << Attr.getName() << ExpectedFunction; 1245 return; 1246 } 1247 1248 D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context)); 1249} 1250 1251static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1252 // Check the attribute arguments. 1253 if (Attr.hasParameterOrArguments()) { 1254 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1255 return; 1256 } 1257 1258 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1259 QualType RetTy = FD->getResultType(); 1260 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 1261 D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context)); 1262 return; 1263 } 1264 } 1265 1266 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 1267} 1268 1269static void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1270 // check the attribute arguments. 1271 if (!checkAttributeNumArgs(S, Attr, 0)) 1272 return; 1273 1274 D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context)); 1275} 1276 1277static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1278 assert(!Attr.isInvalid()); 1279 if (isa<VarDecl>(D)) 1280 D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context)); 1281 else 1282 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1283 << Attr.getName() << ExpectedVariable; 1284} 1285 1286static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1287 assert(!Attr.isInvalid()); 1288 if (isa<VarDecl>(D)) 1289 D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context)); 1290 else 1291 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1292 << Attr.getName() << ExpectedVariable; 1293} 1294 1295static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { 1296 if (hasDeclarator(D)) return; 1297 1298 if (S.CheckNoReturnAttr(attr)) return; 1299 1300 if (!isa<ObjCMethodDecl>(D)) { 1301 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1302 << attr.getName() << ExpectedFunctionOrMethod; 1303 return; 1304 } 1305 1306 D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context)); 1307} 1308 1309bool Sema::CheckNoReturnAttr(const AttributeList &attr) { 1310 if (attr.hasParameterOrArguments()) { 1311 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1312 attr.setInvalid(); 1313 return true; 1314 } 1315 1316 return false; 1317} 1318 1319static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, 1320 const AttributeList &Attr) { 1321 1322 // The checking path for 'noreturn' and 'analyzer_noreturn' are different 1323 // because 'analyzer_noreturn' does not impact the type. 1324 1325 if(!checkAttributeNumArgs(S, Attr, 0)) 1326 return; 1327 1328 if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) { 1329 ValueDecl *VD = dyn_cast<ValueDecl>(D); 1330 if (VD == 0 || (!VD->getType()->isBlockPointerType() 1331 && !VD->getType()->isFunctionPointerType())) { 1332 S.Diag(Attr.getLoc(), 1333 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1334 : diag::warn_attribute_wrong_decl_type) 1335 << Attr.getName() << ExpectedFunctionMethodOrBlock; 1336 return; 1337 } 1338 } 1339 1340 D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context)); 1341} 1342 1343// PS3 PPU-specific. 1344static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1345/* 1346 Returning a Vector Class in Registers 1347 1348 According to the PPU ABI specifications, a class with a single member of 1349 vector type is returned in memory when used as the return value of a function. 1350 This results in inefficient code when implementing vector classes. To return 1351 the value in a single vector register, add the vecreturn attribute to the 1352 class definition. This attribute is also applicable to struct types. 1353 1354 Example: 1355 1356 struct Vector 1357 { 1358 __vector float xyzw; 1359 } __attribute__((vecreturn)); 1360 1361 Vector Add(Vector lhs, Vector rhs) 1362 { 1363 Vector result; 1364 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 1365 return result; // This will be returned in a register 1366 } 1367*/ 1368 if (!isa<RecordDecl>(D)) { 1369 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1370 << Attr.getName() << ExpectedClass; 1371 return; 1372 } 1373 1374 if (D->getAttr<VecReturnAttr>()) { 1375 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 1376 return; 1377 } 1378 1379 RecordDecl *record = cast<RecordDecl>(D); 1380 int count = 0; 1381 1382 if (!isa<CXXRecordDecl>(record)) { 1383 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 1384 return; 1385 } 1386 1387 if (!cast<CXXRecordDecl>(record)->isPOD()) { 1388 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 1389 return; 1390 } 1391 1392 for (RecordDecl::field_iterator iter = record->field_begin(); 1393 iter != record->field_end(); iter++) { 1394 if ((count == 1) || !iter->getType()->isVectorType()) { 1395 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 1396 return; 1397 } 1398 count++; 1399 } 1400 1401 D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context)); 1402} 1403 1404static void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1405 if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) { 1406 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1407 << Attr.getName() << ExpectedFunctionMethodOrParameter; 1408 return; 1409 } 1410 // FIXME: Actually store the attribute on the declaration 1411} 1412 1413static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1414 // check the attribute arguments. 1415 if (Attr.hasParameterOrArguments()) { 1416 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1417 return; 1418 } 1419 1420 if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) && 1421 !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) { 1422 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1423 << Attr.getName() << ExpectedVariableFunctionOrLabel; 1424 return; 1425 } 1426 1427 D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context)); 1428} 1429 1430static void handleReturnsTwiceAttr(Sema &S, Decl *D, 1431 const AttributeList &Attr) { 1432 // check the attribute arguments. 1433 if (Attr.hasParameterOrArguments()) { 1434 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1435 return; 1436 } 1437 1438 if (!isa<FunctionDecl>(D)) { 1439 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1440 << Attr.getName() << ExpectedFunction; 1441 return; 1442 } 1443 1444 D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context)); 1445} 1446 1447static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1448 // check the attribute arguments. 1449 if (Attr.hasParameterOrArguments()) { 1450 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1451 return; 1452 } 1453 1454 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1455 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 1456 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 1457 return; 1458 } 1459 } else if (!isFunctionOrMethod(D)) { 1460 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1461 << Attr.getName() << ExpectedVariableOrFunction; 1462 return; 1463 } 1464 1465 D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context)); 1466} 1467 1468static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1469 // check the attribute arguments. 1470 if (Attr.getNumArgs() > 1) { 1471 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1472 return; 1473 } 1474 1475 int priority = 65535; // FIXME: Do not hardcode such constants. 1476 if (Attr.getNumArgs() > 0) { 1477 Expr *E = Attr.getArg(0); 1478 llvm::APSInt Idx(32); 1479 if (E->isTypeDependent() || E->isValueDependent() || 1480 !E->isIntegerConstantExpr(Idx, S.Context)) { 1481 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1482 << "constructor" << 1 << E->getSourceRange(); 1483 return; 1484 } 1485 priority = Idx.getZExtValue(); 1486 } 1487 1488 if (!isa<FunctionDecl>(D)) { 1489 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1490 << Attr.getName() << ExpectedFunction; 1491 return; 1492 } 1493 1494 D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context, 1495 priority)); 1496} 1497 1498static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1499 // check the attribute arguments. 1500 if (Attr.getNumArgs() > 1) { 1501 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1502 return; 1503 } 1504 1505 int priority = 65535; // FIXME: Do not hardcode such constants. 1506 if (Attr.getNumArgs() > 0) { 1507 Expr *E = Attr.getArg(0); 1508 llvm::APSInt Idx(32); 1509 if (E->isTypeDependent() || E->isValueDependent() || 1510 !E->isIntegerConstantExpr(Idx, S.Context)) { 1511 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1512 << "destructor" << 1 << E->getSourceRange(); 1513 return; 1514 } 1515 priority = Idx.getZExtValue(); 1516 } 1517 1518 if (!isa<FunctionDecl>(D)) { 1519 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1520 << Attr.getName() << ExpectedFunction; 1521 return; 1522 } 1523 1524 D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context, 1525 priority)); 1526} 1527 1528static void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1529 unsigned NumArgs = Attr.getNumArgs(); 1530 if (NumArgs > 1) { 1531 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1532 return; 1533 } 1534 1535 // Handle the case where deprecated attribute has a text message. 1536 StringRef Str; 1537 if (NumArgs == 1) { 1538 StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1539 if (!SE) { 1540 S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string) 1541 << "deprecated"; 1542 return; 1543 } 1544 Str = SE->getString(); 1545 } 1546 1547 D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str)); 1548} 1549 1550static void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1551 unsigned NumArgs = Attr.getNumArgs(); 1552 if (NumArgs > 1) { 1553 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1554 return; 1555 } 1556 1557 // Handle the case where unavailable attribute has a text message. 1558 StringRef Str; 1559 if (NumArgs == 1) { 1560 StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1561 if (!SE) { 1562 S.Diag(Attr.getArg(0)->getLocStart(), 1563 diag::err_attribute_not_string) << "unavailable"; 1564 return; 1565 } 1566 Str = SE->getString(); 1567 } 1568 D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str)); 1569} 1570 1571static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, 1572 const AttributeList &Attr) { 1573 unsigned NumArgs = Attr.getNumArgs(); 1574 if (NumArgs > 0) { 1575 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1576 return; 1577 } 1578 1579 D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr( 1580 Attr.getRange(), S.Context)); 1581} 1582 1583static void handleAvailabilityAttr(Sema &S, Decl *D, 1584 const AttributeList &Attr) { 1585 IdentifierInfo *Platform = Attr.getParameterName(); 1586 SourceLocation PlatformLoc = Attr.getParameterLoc(); 1587 1588 StringRef PlatformName 1589 = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 1590 if (PlatformName.empty()) { 1591 S.Diag(PlatformLoc, diag::warn_availability_unknown_platform) 1592 << Platform; 1593 1594 PlatformName = Platform->getName(); 1595 } 1596 1597 AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 1598 AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 1599 AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 1600 bool IsUnavailable = Attr.getUnavailableLoc().isValid(); 1601 1602 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all 1603 // of these steps are needed). 1604 if (Introduced.isValid() && Deprecated.isValid() && 1605 !(Introduced.Version <= Deprecated.Version)) { 1606 S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 1607 << 1 << PlatformName << Deprecated.Version.getAsString() 1608 << 0 << Introduced.Version.getAsString(); 1609 return; 1610 } 1611 1612 if (Introduced.isValid() && Obsoleted.isValid() && 1613 !(Introduced.Version <= Obsoleted.Version)) { 1614 S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 1615 << 2 << PlatformName << Obsoleted.Version.getAsString() 1616 << 0 << Introduced.Version.getAsString(); 1617 return; 1618 } 1619 1620 if (Deprecated.isValid() && Obsoleted.isValid() && 1621 !(Deprecated.Version <= Obsoleted.Version)) { 1622 S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering) 1623 << 2 << PlatformName << Obsoleted.Version.getAsString() 1624 << 1 << Deprecated.Version.getAsString(); 1625 return; 1626 } 1627 1628 D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context, 1629 Platform, 1630 Introduced.Version, 1631 Deprecated.Version, 1632 Obsoleted.Version, 1633 IsUnavailable)); 1634} 1635 1636static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1637 // check the attribute arguments. 1638 if(!checkAttributeNumArgs(S, Attr, 1)) 1639 return; 1640 1641 Expr *Arg = Attr.getArg(0); 1642 Arg = Arg->IgnoreParenCasts(); 1643 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1644 1645 if (!Str || !Str->isAscii()) { 1646 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1647 << "visibility" << 1; 1648 return; 1649 } 1650 1651 StringRef TypeStr = Str->getString(); 1652 VisibilityAttr::VisibilityType type; 1653 1654 if (TypeStr == "default") 1655 type = VisibilityAttr::Default; 1656 else if (TypeStr == "hidden") 1657 type = VisibilityAttr::Hidden; 1658 else if (TypeStr == "internal") 1659 type = VisibilityAttr::Hidden; // FIXME 1660 else if (TypeStr == "protected") 1661 type = VisibilityAttr::Protected; 1662 else { 1663 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 1664 return; 1665 } 1666 1667 D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type)); 1668} 1669 1670static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, 1671 const AttributeList &Attr) { 1672 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl); 1673 if (!method) { 1674 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1675 << ExpectedMethod; 1676 return; 1677 } 1678 1679 if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) { 1680 if (!Attr.getParameterName() && Attr.getNumArgs() == 1) { 1681 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1682 << "objc_method_family" << 1; 1683 } else { 1684 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1685 } 1686 Attr.setInvalid(); 1687 return; 1688 } 1689 1690 StringRef param = Attr.getParameterName()->getName(); 1691 ObjCMethodFamilyAttr::FamilyKind family; 1692 if (param == "none") 1693 family = ObjCMethodFamilyAttr::OMF_None; 1694 else if (param == "alloc") 1695 family = ObjCMethodFamilyAttr::OMF_alloc; 1696 else if (param == "copy") 1697 family = ObjCMethodFamilyAttr::OMF_copy; 1698 else if (param == "init") 1699 family = ObjCMethodFamilyAttr::OMF_init; 1700 else if (param == "mutableCopy") 1701 family = ObjCMethodFamilyAttr::OMF_mutableCopy; 1702 else if (param == "new") 1703 family = ObjCMethodFamilyAttr::OMF_new; 1704 else { 1705 // Just warn and ignore it. This is future-proof against new 1706 // families being used in system headers. 1707 S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family); 1708 return; 1709 } 1710 1711 if (family == ObjCMethodFamilyAttr::OMF_init && 1712 !method->getResultType()->isObjCObjectPointerType()) { 1713 S.Diag(method->getLocation(), diag::err_init_method_bad_return_type) 1714 << method->getResultType(); 1715 // Ignore the attribute. 1716 return; 1717 } 1718 1719 method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(), 1720 S.Context, family)); 1721} 1722 1723static void handleObjCExceptionAttr(Sema &S, Decl *D, 1724 const AttributeList &Attr) { 1725 if (!checkAttributeNumArgs(S, Attr, 0)) 1726 return; 1727 1728 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 1729 if (OCI == 0) { 1730 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 1731 return; 1732 } 1733 1734 D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context)); 1735} 1736 1737static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { 1738 if (Attr.getNumArgs() != 0) { 1739 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1740 return; 1741 } 1742 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 1743 QualType T = TD->getUnderlyingType(); 1744 if (!T->isPointerType() || 1745 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 1746 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 1747 return; 1748 } 1749 } 1750 D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context)); 1751} 1752 1753static void 1754handleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1755 if (Attr.getNumArgs() != 0) { 1756 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1757 return; 1758 } 1759 1760 if (!isa<FunctionDecl>(D)) { 1761 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 1762 return; 1763 } 1764 1765 D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context)); 1766} 1767 1768static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1769 if (!Attr.getParameterName()) { 1770 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1771 << "blocks" << 1; 1772 return; 1773 } 1774 1775 if (Attr.getNumArgs() != 0) { 1776 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1777 return; 1778 } 1779 1780 BlocksAttr::BlockType type; 1781 if (Attr.getParameterName()->isStr("byref")) 1782 type = BlocksAttr::ByRef; 1783 else { 1784 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1785 << "blocks" << Attr.getParameterName(); 1786 return; 1787 } 1788 1789 D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type)); 1790} 1791 1792static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1793 // check the attribute arguments. 1794 if (Attr.getNumArgs() > 2) { 1795 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 1796 return; 1797 } 1798 1799 unsigned sentinel = 0; 1800 if (Attr.getNumArgs() > 0) { 1801 Expr *E = Attr.getArg(0); 1802 llvm::APSInt Idx(32); 1803 if (E->isTypeDependent() || E->isValueDependent() || 1804 !E->isIntegerConstantExpr(Idx, S.Context)) { 1805 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1806 << "sentinel" << 1 << E->getSourceRange(); 1807 return; 1808 } 1809 1810 if (Idx.isSigned() && Idx.isNegative()) { 1811 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 1812 << E->getSourceRange(); 1813 return; 1814 } 1815 1816 sentinel = Idx.getZExtValue(); 1817 } 1818 1819 unsigned nullPos = 0; 1820 if (Attr.getNumArgs() > 1) { 1821 Expr *E = Attr.getArg(1); 1822 llvm::APSInt Idx(32); 1823 if (E->isTypeDependent() || E->isValueDependent() || 1824 !E->isIntegerConstantExpr(Idx, S.Context)) { 1825 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1826 << "sentinel" << 2 << E->getSourceRange(); 1827 return; 1828 } 1829 nullPos = Idx.getZExtValue(); 1830 1831 if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) { 1832 // FIXME: This error message could be improved, it would be nice 1833 // to say what the bounds actually are. 1834 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1835 << E->getSourceRange(); 1836 return; 1837 } 1838 } 1839 1840 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1841 const FunctionType *FT = FD->getType()->castAs<FunctionType>(); 1842 if (isa<FunctionNoProtoType>(FT)) { 1843 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1844 return; 1845 } 1846 1847 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 1848 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1849 return; 1850 } 1851 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 1852 if (!MD->isVariadic()) { 1853 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1854 return; 1855 } 1856 } else if (isa<BlockDecl>(D)) { 1857 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 1858 // caller. 1859 ; 1860 } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 1861 QualType Ty = V->getType(); 1862 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 1863 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D) 1864 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 1865 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 1866 int m = Ty->isFunctionPointerType() ? 0 : 1; 1867 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 1868 return; 1869 } 1870 } else { 1871 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1872 << Attr.getName() << ExpectedFunctionMethodOrBlock; 1873 return; 1874 } 1875 } else { 1876 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1877 << Attr.getName() << ExpectedFunctionMethodOrBlock; 1878 return; 1879 } 1880 D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel, 1881 nullPos)); 1882} 1883 1884static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) { 1885 // check the attribute arguments. 1886 if (!checkAttributeNumArgs(S, Attr, 0)) 1887 return; 1888 1889 if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1890 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1891 << Attr.getName() << ExpectedFunctionOrMethod; 1892 return; 1893 } 1894 1895 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1896 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1897 << Attr.getName() << 0; 1898 return; 1899 } 1900 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1901 if (MD->getResultType()->isVoidType()) { 1902 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1903 << Attr.getName() << 1; 1904 return; 1905 } 1906 1907 D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context)); 1908} 1909 1910static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1911 // check the attribute arguments. 1912 if (Attr.hasParameterOrArguments()) { 1913 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1914 return; 1915 } 1916 1917 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 1918 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1919 << Attr.getName() << ExpectedVariableOrFunction; 1920 return; 1921 } 1922 1923 NamedDecl *nd = cast<NamedDecl>(D); 1924 1925 // 'weak' only applies to declarations with external linkage. 1926 if (hasEffectivelyInternalLinkage(nd)) { 1927 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static); 1928 return; 1929 } 1930 1931 nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 1932} 1933 1934static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1935 // check the attribute arguments. 1936 if (!checkAttributeNumArgs(S, Attr, 0)) 1937 return; 1938 1939 1940 // weak_import only applies to variable & function declarations. 1941 bool isDef = false; 1942 if (!D->canBeWeakImported(isDef)) { 1943 if (isDef) 1944 S.Diag(Attr.getLoc(), 1945 diag::warn_attribute_weak_import_invalid_on_definition) 1946 << "weak_import" << 2 /*variable and function*/; 1947 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 1948 (S.Context.getTargetInfo().getTriple().isOSDarwin() && 1949 isa<ObjCInterfaceDecl>(D))) { 1950 // Nothing to warn about here. 1951 } else 1952 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1953 << Attr.getName() << ExpectedVariableOrFunction; 1954 1955 return; 1956 } 1957 1958 D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context)); 1959} 1960 1961static void handleReqdWorkGroupSize(Sema &S, Decl *D, 1962 const AttributeList &Attr) { 1963 // Attribute has 3 arguments. 1964 if (!checkAttributeNumArgs(S, Attr, 3)) 1965 return; 1966 1967 unsigned WGSize[3]; 1968 for (unsigned i = 0; i < 3; ++i) { 1969 Expr *E = Attr.getArg(i); 1970 llvm::APSInt ArgNum(32); 1971 if (E->isTypeDependent() || E->isValueDependent() || 1972 !E->isIntegerConstantExpr(ArgNum, S.Context)) { 1973 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1974 << "reqd_work_group_size" << E->getSourceRange(); 1975 return; 1976 } 1977 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 1978 } 1979 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context, 1980 WGSize[0], WGSize[1], 1981 WGSize[2])); 1982} 1983 1984static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1985 // Attribute has no arguments. 1986 if (!checkAttributeNumArgs(S, Attr, 1)) 1987 return; 1988 1989 // Make sure that there is a string literal as the sections's single 1990 // argument. 1991 Expr *ArgExpr = Attr.getArg(0); 1992 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1993 if (!SE) { 1994 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 1995 return; 1996 } 1997 1998 // If the target wants to validate the section specifier, make it happen. 1999 std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString()); 2000 if (!Error.empty()) { 2001 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 2002 << Error; 2003 return; 2004 } 2005 2006 // This attribute cannot be applied to local variables. 2007 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 2008 S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 2009 return; 2010 } 2011 2012 D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context, 2013 SE->getString())); 2014} 2015 2016 2017static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2018 // check the attribute arguments. 2019 if (Attr.hasParameterOrArguments()) { 2020 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2021 return; 2022 } 2023 2024 if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) { 2025 if (Existing->getLocation().isInvalid()) 2026 Existing->setRange(Attr.getRange()); 2027 } else { 2028 D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context)); 2029 } 2030} 2031 2032static void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2033 // check the attribute arguments. 2034 if (Attr.hasParameterOrArguments()) { 2035 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2036 return; 2037 } 2038 2039 if (ConstAttr *Existing = D->getAttr<ConstAttr>()) { 2040 if (Existing->getLocation().isInvalid()) 2041 Existing->setRange(Attr.getRange()); 2042 } else { 2043 D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context)); 2044 } 2045} 2046 2047static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2048 // check the attribute arguments. 2049 if (!checkAttributeNumArgs(S, Attr, 0)) 2050 return; 2051 2052 D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context)); 2053} 2054 2055static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2056 if (!Attr.getParameterName()) { 2057 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2058 return; 2059 } 2060 2061 if (Attr.getNumArgs() != 0) { 2062 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2063 return; 2064 } 2065 2066 VarDecl *VD = dyn_cast<VarDecl>(D); 2067 2068 if (!VD || !VD->hasLocalStorage()) { 2069 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 2070 return; 2071 } 2072 2073 // Look up the function 2074 // FIXME: Lookup probably isn't looking in the right place 2075 NamedDecl *CleanupDecl 2076 = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 2077 Attr.getParameterLoc(), Sema::LookupOrdinaryName); 2078 if (!CleanupDecl) { 2079 S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 2080 Attr.getParameterName(); 2081 return; 2082 } 2083 2084 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 2085 if (!FD) { 2086 S.Diag(Attr.getParameterLoc(), 2087 diag::err_attribute_cleanup_arg_not_function) 2088 << Attr.getParameterName(); 2089 return; 2090 } 2091 2092 if (FD->getNumParams() != 1) { 2093 S.Diag(Attr.getParameterLoc(), 2094 diag::err_attribute_cleanup_func_must_take_one_arg) 2095 << Attr.getParameterName(); 2096 return; 2097 } 2098 2099 // We're currently more strict than GCC about what function types we accept. 2100 // If this ever proves to be a problem it should be easy to fix. 2101 QualType Ty = S.Context.getPointerType(VD->getType()); 2102 QualType ParamTy = FD->getParamDecl(0)->getType(); 2103 if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 2104 ParamTy, Ty) != Sema::Compatible) { 2105 S.Diag(Attr.getParameterLoc(), 2106 diag::err_attribute_cleanup_func_arg_incompatible_type) << 2107 Attr.getParameterName() << ParamTy << Ty; 2108 return; 2109 } 2110 2111 D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD)); 2112 S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD); 2113} 2114 2115/// Handle __attribute__((format_arg((idx)))) attribute based on 2116/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 2117static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2118 if (!checkAttributeNumArgs(S, Attr, 1)) 2119 return; 2120 2121 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 2122 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2123 << Attr.getName() << ExpectedFunction; 2124 return; 2125 } 2126 2127 // In C++ the implicit 'this' function parameter also counts, and they are 2128 // counted from one. 2129 bool HasImplicitThisParam = isInstanceMethod(D); 2130 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 2131 unsigned FirstIdx = 1; 2132 2133 // checks for the 2nd argument 2134 Expr *IdxExpr = Attr.getArg(0); 2135 llvm::APSInt Idx(32); 2136 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2137 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 2138 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 2139 << "format" << 2 << IdxExpr->getSourceRange(); 2140 return; 2141 } 2142 2143 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 2144 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 2145 << "format" << 2 << IdxExpr->getSourceRange(); 2146 return; 2147 } 2148 2149 unsigned ArgIdx = Idx.getZExtValue() - 1; 2150 2151 if (HasImplicitThisParam) { 2152 if (ArgIdx == 0) { 2153 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 2154 << "format_arg" << IdxExpr->getSourceRange(); 2155 return; 2156 } 2157 ArgIdx--; 2158 } 2159 2160 // make sure the format string is really a string 2161 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 2162 2163 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 2164 if (not_nsstring_type && 2165 !isCFStringType(Ty, S.Context) && 2166 (!Ty->isPointerType() || 2167 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 2168 // FIXME: Should highlight the actual expression that has the wrong type. 2169 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2170 << (not_nsstring_type ? "a string type" : "an NSString") 2171 << IdxExpr->getSourceRange(); 2172 return; 2173 } 2174 Ty = getFunctionOrMethodResultType(D); 2175 if (!isNSStringType(Ty, S.Context) && 2176 !isCFStringType(Ty, S.Context) && 2177 (!Ty->isPointerType() || 2178 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 2179 // FIXME: Should highlight the actual expression that has the wrong type. 2180 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 2181 << (not_nsstring_type ? "string type" : "NSString") 2182 << IdxExpr->getSourceRange(); 2183 return; 2184 } 2185 2186 D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context, 2187 Idx.getZExtValue())); 2188} 2189 2190enum FormatAttrKind { 2191 CFStringFormat, 2192 NSStringFormat, 2193 StrftimeFormat, 2194 SupportedFormat, 2195 IgnoredFormat, 2196 InvalidFormat 2197}; 2198 2199/// getFormatAttrKind - Map from format attribute names to supported format 2200/// types. 2201static FormatAttrKind getFormatAttrKind(StringRef Format) { 2202 // Check for formats that get handled specially. 2203 if (Format == "NSString") 2204 return NSStringFormat; 2205 if (Format == "CFString") 2206 return CFStringFormat; 2207 if (Format == "strftime") 2208 return StrftimeFormat; 2209 2210 // Otherwise, check for supported formats. 2211 if (Format == "scanf" || Format == "printf" || Format == "printf0" || 2212 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 2213 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 2214 Format == "zcmn_err" || 2215 Format == "kprintf") // OpenBSD. 2216 return SupportedFormat; 2217 2218 if (Format == "gcc_diag" || Format == "gcc_cdiag" || 2219 Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 2220 return IgnoredFormat; 2221 2222 return InvalidFormat; 2223} 2224 2225/// Handle __attribute__((init_priority(priority))) attributes based on 2226/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 2227static void handleInitPriorityAttr(Sema &S, Decl *D, 2228 const AttributeList &Attr) { 2229 if (!S.getLangOptions().CPlusPlus) { 2230 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2231 return; 2232 } 2233 2234 if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) { 2235 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2236 Attr.setInvalid(); 2237 return; 2238 } 2239 QualType T = dyn_cast<VarDecl>(D)->getType(); 2240 if (S.Context.getAsArrayType(T)) 2241 T = S.Context.getBaseElementType(T); 2242 if (!T->getAs<RecordType>()) { 2243 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2244 Attr.setInvalid(); 2245 return; 2246 } 2247 2248 if (Attr.getNumArgs() != 1) { 2249 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2250 Attr.setInvalid(); 2251 return; 2252 } 2253 Expr *priorityExpr = Attr.getArg(0); 2254 2255 llvm::APSInt priority(32); 2256 if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 2257 !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 2258 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 2259 << "init_priority" << priorityExpr->getSourceRange(); 2260 Attr.setInvalid(); 2261 return; 2262 } 2263 unsigned prioritynum = priority.getZExtValue(); 2264 if (prioritynum < 101 || prioritynum > 65535) { 2265 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 2266 << priorityExpr->getSourceRange(); 2267 Attr.setInvalid(); 2268 return; 2269 } 2270 D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context, 2271 prioritynum)); 2272} 2273 2274/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 2275/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 2276static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2277 2278 if (!Attr.getParameterName()) { 2279 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 2280 << "format" << 1; 2281 return; 2282 } 2283 2284 if (Attr.getNumArgs() != 2) { 2285 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 2286 return; 2287 } 2288 2289 if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) { 2290 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2291 << Attr.getName() << ExpectedFunction; 2292 return; 2293 } 2294 2295 // In C++ the implicit 'this' function parameter also counts, and they are 2296 // counted from one. 2297 bool HasImplicitThisParam = isInstanceMethod(D); 2298 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 2299 unsigned FirstIdx = 1; 2300 2301 StringRef Format = Attr.getParameterName()->getName(); 2302 2303 // Normalize the argument, __foo__ becomes foo. 2304 if (Format.startswith("__") && Format.endswith("__")) 2305 Format = Format.substr(2, Format.size() - 4); 2306 2307 // Check for supported formats. 2308 FormatAttrKind Kind = getFormatAttrKind(Format); 2309 2310 if (Kind == IgnoredFormat) 2311 return; 2312 2313 if (Kind == InvalidFormat) { 2314 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 2315 << "format" << Attr.getParameterName()->getName(); 2316 return; 2317 } 2318 2319 // checks for the 2nd argument 2320 Expr *IdxExpr = Attr.getArg(0); 2321 llvm::APSInt Idx(32); 2322 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2323 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 2324 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 2325 << "format" << 2 << IdxExpr->getSourceRange(); 2326 return; 2327 } 2328 2329 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 2330 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 2331 << "format" << 2 << IdxExpr->getSourceRange(); 2332 return; 2333 } 2334 2335 // FIXME: Do we need to bounds check? 2336 unsigned ArgIdx = Idx.getZExtValue() - 1; 2337 2338 if (HasImplicitThisParam) { 2339 if (ArgIdx == 0) { 2340 S.Diag(Attr.getLoc(), 2341 diag::err_format_attribute_implicit_this_format_string) 2342 << IdxExpr->getSourceRange(); 2343 return; 2344 } 2345 ArgIdx--; 2346 } 2347 2348 // make sure the format string is really a string 2349 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 2350 2351 if (Kind == CFStringFormat) { 2352 if (!isCFStringType(Ty, S.Context)) { 2353 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2354 << "a CFString" << IdxExpr->getSourceRange(); 2355 return; 2356 } 2357 } else if (Kind == NSStringFormat) { 2358 // FIXME: do we need to check if the type is NSString*? What are the 2359 // semantics? 2360 if (!isNSStringType(Ty, S.Context)) { 2361 // FIXME: Should highlight the actual expression that has the wrong type. 2362 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2363 << "an NSString" << IdxExpr->getSourceRange(); 2364 return; 2365 } 2366 } else if (!Ty->isPointerType() || 2367 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 2368 // FIXME: Should highlight the actual expression that has the wrong type. 2369 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2370 << "a string type" << IdxExpr->getSourceRange(); 2371 return; 2372 } 2373 2374 // check the 3rd argument 2375 Expr *FirstArgExpr = Attr.getArg(1); 2376 llvm::APSInt FirstArg(32); 2377 if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 2378 !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 2379 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 2380 << "format" << 3 << FirstArgExpr->getSourceRange(); 2381 return; 2382 } 2383 2384 // check if the function is variadic if the 3rd argument non-zero 2385 if (FirstArg != 0) { 2386 if (isFunctionOrMethodVariadic(D)) { 2387 ++NumArgs; // +1 for ... 2388 } else { 2389 S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); 2390 return; 2391 } 2392 } 2393 2394 // strftime requires FirstArg to be 0 because it doesn't read from any 2395 // variable the input is just the current time + the format string. 2396 if (Kind == StrftimeFormat) { 2397 if (FirstArg != 0) { 2398 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 2399 << FirstArgExpr->getSourceRange(); 2400 return; 2401 } 2402 // if 0 it disables parameter checking (to use with e.g. va_list) 2403 } else if (FirstArg != 0 && FirstArg != NumArgs) { 2404 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 2405 << "format" << 3 << FirstArgExpr->getSourceRange(); 2406 return; 2407 } 2408 2409 // Check whether we already have an equivalent format attribute. 2410 for (specific_attr_iterator<FormatAttr> 2411 i = D->specific_attr_begin<FormatAttr>(), 2412 e = D->specific_attr_end<FormatAttr>(); 2413 i != e ; ++i) { 2414 FormatAttr *f = *i; 2415 if (f->getType() == Format && 2416 f->getFormatIdx() == (int)Idx.getZExtValue() && 2417 f->getFirstArg() == (int)FirstArg.getZExtValue()) { 2418 // If we don't have a valid location for this attribute, adopt the 2419 // location. 2420 if (f->getLocation().isInvalid()) 2421 f->setRange(Attr.getRange()); 2422 return; 2423 } 2424 } 2425 2426 D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format, 2427 Idx.getZExtValue(), 2428 FirstArg.getZExtValue())); 2429} 2430 2431static void handleTransparentUnionAttr(Sema &S, Decl *D, 2432 const AttributeList &Attr) { 2433 // check the attribute arguments. 2434 if (!checkAttributeNumArgs(S, Attr, 0)) 2435 return; 2436 2437 2438 // Try to find the underlying union declaration. 2439 RecordDecl *RD = 0; 2440 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 2441 if (TD && TD->getUnderlyingType()->isUnionType()) 2442 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 2443 else 2444 RD = dyn_cast<RecordDecl>(D); 2445 2446 if (!RD || !RD->isUnion()) { 2447 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2448 << Attr.getName() << ExpectedUnion; 2449 return; 2450 } 2451 2452 if (!RD->isDefinition()) { 2453 S.Diag(Attr.getLoc(), 2454 diag::warn_transparent_union_attribute_not_definition); 2455 return; 2456 } 2457 2458 RecordDecl::field_iterator Field = RD->field_begin(), 2459 FieldEnd = RD->field_end(); 2460 if (Field == FieldEnd) { 2461 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 2462 return; 2463 } 2464 2465 FieldDecl *FirstField = *Field; 2466 QualType FirstType = FirstField->getType(); 2467 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 2468 S.Diag(FirstField->getLocation(), 2469 diag::warn_transparent_union_attribute_floating) 2470 << FirstType->isVectorType() << FirstType; 2471 return; 2472 } 2473 2474 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 2475 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 2476 for (; Field != FieldEnd; ++Field) { 2477 QualType FieldType = Field->getType(); 2478 if (S.Context.getTypeSize(FieldType) != FirstSize || 2479 S.Context.getTypeAlign(FieldType) != FirstAlign) { 2480 // Warn if we drop the attribute. 2481 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 2482 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 2483 : S.Context.getTypeAlign(FieldType); 2484 S.Diag(Field->getLocation(), 2485 diag::warn_transparent_union_attribute_field_size_align) 2486 << isSize << Field->getDeclName() << FieldBits; 2487 unsigned FirstBits = isSize? FirstSize : FirstAlign; 2488 S.Diag(FirstField->getLocation(), 2489 diag::note_transparent_union_first_field_size_align) 2490 << isSize << FirstBits; 2491 return; 2492 } 2493 } 2494 2495 RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context)); 2496} 2497 2498static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2499 // check the attribute arguments. 2500 if (!checkAttributeNumArgs(S, Attr, 1)) 2501 return; 2502 2503 Expr *ArgExpr = Attr.getArg(0); 2504 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 2505 2506 // Make sure that there is a string literal as the annotation's single 2507 // argument. 2508 if (!SE) { 2509 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 2510 return; 2511 } 2512 2513 // Don't duplicate annotations that are already set. 2514 for (specific_attr_iterator<AnnotateAttr> 2515 i = D->specific_attr_begin<AnnotateAttr>(), 2516 e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) { 2517 if ((*i)->getAnnotation() == SE->getString()) 2518 return; 2519 } 2520 D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context, 2521 SE->getString())); 2522} 2523 2524static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2525 // check the attribute arguments. 2526 if (Attr.getNumArgs() > 1) { 2527 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2528 return; 2529 } 2530 2531 //FIXME: The C++0x version of this attribute has more limited applicabilty 2532 // than GNU's, and should error out when it is used to specify a 2533 // weaker alignment, rather than being silently ignored. 2534 2535 if (Attr.getNumArgs() == 0) { 2536 D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0)); 2537 return; 2538 } 2539 2540 S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0)); 2541} 2542 2543void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) { 2544 if (E->isTypeDependent() || E->isValueDependent()) { 2545 // Save dependent expressions in the AST to be instantiated. 2546 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); 2547 return; 2548 } 2549 2550 SourceLocation AttrLoc = AttrRange.getBegin(); 2551 // FIXME: Cache the number on the Attr object? 2552 llvm::APSInt Alignment(32); 2553 if (!E->isIntegerConstantExpr(Alignment, Context)) { 2554 Diag(AttrLoc, diag::err_attribute_argument_not_int) 2555 << "aligned" << E->getSourceRange(); 2556 return; 2557 } 2558 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 2559 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 2560 << E->getSourceRange(); 2561 return; 2562 } 2563 2564 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); 2565} 2566 2567void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) { 2568 // FIXME: Cache the number on the Attr object if non-dependent? 2569 // FIXME: Perform checking of type validity 2570 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS)); 2571 return; 2572} 2573 2574/// handleModeAttr - This attribute modifies the width of a decl with primitive 2575/// type. 2576/// 2577/// Despite what would be logical, the mode attribute is a decl attribute, not a 2578/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 2579/// HImode, not an intermediate pointer. 2580static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2581 // This attribute isn't documented, but glibc uses it. It changes 2582 // the width of an int or unsigned int to the specified size. 2583 2584 // Check that there aren't any arguments 2585 if (!checkAttributeNumArgs(S, Attr, 0)) 2586 return; 2587 2588 2589 IdentifierInfo *Name = Attr.getParameterName(); 2590 if (!Name) { 2591 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 2592 return; 2593 } 2594 2595 StringRef Str = Attr.getParameterName()->getName(); 2596 2597 // Normalize the attribute name, __foo__ becomes foo. 2598 if (Str.startswith("__") && Str.endswith("__")) 2599 Str = Str.substr(2, Str.size() - 4); 2600 2601 unsigned DestWidth = 0; 2602 bool IntegerMode = true; 2603 bool ComplexMode = false; 2604 switch (Str.size()) { 2605 case 2: 2606 switch (Str[0]) { 2607 case 'Q': DestWidth = 8; break; 2608 case 'H': DestWidth = 16; break; 2609 case 'S': DestWidth = 32; break; 2610 case 'D': DestWidth = 64; break; 2611 case 'X': DestWidth = 96; break; 2612 case 'T': DestWidth = 128; break; 2613 } 2614 if (Str[1] == 'F') { 2615 IntegerMode = false; 2616 } else if (Str[1] == 'C') { 2617 IntegerMode = false; 2618 ComplexMode = true; 2619 } else if (Str[1] != 'I') { 2620 DestWidth = 0; 2621 } 2622 break; 2623 case 4: 2624 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 2625 // pointer on PIC16 and other embedded platforms. 2626 if (Str == "word") 2627 DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2628 else if (Str == "byte") 2629 DestWidth = S.Context.getTargetInfo().getCharWidth(); 2630 break; 2631 case 7: 2632 if (Str == "pointer") 2633 DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2634 break; 2635 } 2636 2637 QualType OldTy; 2638 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 2639 OldTy = TD->getUnderlyingType(); 2640 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 2641 OldTy = VD->getType(); 2642 else { 2643 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 2644 << "mode" << Attr.getRange(); 2645 return; 2646 } 2647 2648 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 2649 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 2650 else if (IntegerMode) { 2651 if (!OldTy->isIntegralOrEnumerationType()) 2652 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 2653 } else if (ComplexMode) { 2654 if (!OldTy->isComplexType()) 2655 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 2656 } else { 2657 if (!OldTy->isFloatingType()) 2658 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 2659 } 2660 2661 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 2662 // and friends, at least with glibc. 2663 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 2664 // width on unusual platforms. 2665 // FIXME: Make sure floating-point mappings are accurate 2666 // FIXME: Support XF and TF types 2667 QualType NewTy; 2668 switch (DestWidth) { 2669 case 0: 2670 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 2671 return; 2672 default: 2673 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2674 return; 2675 case 8: 2676 if (!IntegerMode) { 2677 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2678 return; 2679 } 2680 if (OldTy->isSignedIntegerType()) 2681 NewTy = S.Context.SignedCharTy; 2682 else 2683 NewTy = S.Context.UnsignedCharTy; 2684 break; 2685 case 16: 2686 if (!IntegerMode) { 2687 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2688 return; 2689 } 2690 if (OldTy->isSignedIntegerType()) 2691 NewTy = S.Context.ShortTy; 2692 else 2693 NewTy = S.Context.UnsignedShortTy; 2694 break; 2695 case 32: 2696 if (!IntegerMode) 2697 NewTy = S.Context.FloatTy; 2698 else if (OldTy->isSignedIntegerType()) 2699 NewTy = S.Context.IntTy; 2700 else 2701 NewTy = S.Context.UnsignedIntTy; 2702 break; 2703 case 64: 2704 if (!IntegerMode) 2705 NewTy = S.Context.DoubleTy; 2706 else if (OldTy->isSignedIntegerType()) 2707 if (S.Context.getTargetInfo().getLongWidth() == 64) 2708 NewTy = S.Context.LongTy; 2709 else 2710 NewTy = S.Context.LongLongTy; 2711 else 2712 if (S.Context.getTargetInfo().getLongWidth() == 64) 2713 NewTy = S.Context.UnsignedLongTy; 2714 else 2715 NewTy = S.Context.UnsignedLongLongTy; 2716 break; 2717 case 96: 2718 NewTy = S.Context.LongDoubleTy; 2719 break; 2720 case 128: 2721 if (!IntegerMode) { 2722 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2723 return; 2724 } 2725 if (OldTy->isSignedIntegerType()) 2726 NewTy = S.Context.Int128Ty; 2727 else 2728 NewTy = S.Context.UnsignedInt128Ty; 2729 break; 2730 } 2731 2732 if (ComplexMode) { 2733 NewTy = S.Context.getComplexType(NewTy); 2734 } 2735 2736 // Install the new type. 2737 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 2738 // FIXME: preserve existing source info. 2739 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 2740 } else 2741 cast<ValueDecl>(D)->setType(NewTy); 2742} 2743 2744static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2745 // check the attribute arguments. 2746 if (!checkAttributeNumArgs(S, Attr, 0)) 2747 return; 2748 2749 if (!isFunctionOrMethod(D)) { 2750 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2751 << Attr.getName() << ExpectedFunction; 2752 return; 2753 } 2754 2755 D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context)); 2756} 2757 2758static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2759 // check the attribute arguments. 2760 if (!checkAttributeNumArgs(S, Attr, 0)) 2761 return; 2762 2763 2764 if (!isa<FunctionDecl>(D)) { 2765 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2766 << Attr.getName() << ExpectedFunction; 2767 return; 2768 } 2769 2770 D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context)); 2771} 2772 2773static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D, 2774 const AttributeList &Attr) { 2775 // check the attribute arguments. 2776 if (!checkAttributeNumArgs(S, Attr, 0)) 2777 return; 2778 2779 2780 if (!isa<FunctionDecl>(D)) { 2781 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2782 << Attr.getName() << ExpectedFunction; 2783 return; 2784 } 2785 2786 D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(), 2787 S.Context)); 2788} 2789 2790static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2791 if (S.LangOpts.CUDA) { 2792 // check the attribute arguments. 2793 if (Attr.hasParameterOrArguments()) { 2794 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2795 return; 2796 } 2797 2798 if (!isa<VarDecl>(D)) { 2799 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2800 << Attr.getName() << ExpectedVariable; 2801 return; 2802 } 2803 2804 D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context)); 2805 } else { 2806 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 2807 } 2808} 2809 2810static void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2811 if (S.LangOpts.CUDA) { 2812 // check the attribute arguments. 2813 if (Attr.getNumArgs() != 0) { 2814 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2815 return; 2816 } 2817 2818 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 2819 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2820 << Attr.getName() << ExpectedVariableOrFunction; 2821 return; 2822 } 2823 2824 D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context)); 2825 } else { 2826 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 2827 } 2828} 2829 2830static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2831 if (S.LangOpts.CUDA) { 2832 // check the attribute arguments. 2833 if (!checkAttributeNumArgs(S, Attr, 0)) 2834 return; 2835 2836 if (!isa<FunctionDecl>(D)) { 2837 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2838 << Attr.getName() << ExpectedFunction; 2839 return; 2840 } 2841 2842 FunctionDecl *FD = cast<FunctionDecl>(D); 2843 if (!FD->getResultType()->isVoidType()) { 2844 TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 2845 if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 2846 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 2847 << FD->getType() 2848 << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 2849 "void"); 2850 } else { 2851 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 2852 << FD->getType(); 2853 } 2854 return; 2855 } 2856 2857 D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context)); 2858 } else { 2859 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 2860 } 2861} 2862 2863static void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2864 if (S.LangOpts.CUDA) { 2865 // check the attribute arguments. 2866 if (!checkAttributeNumArgs(S, Attr, 0)) 2867 return; 2868 2869 2870 if (!isa<FunctionDecl>(D)) { 2871 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2872 << Attr.getName() << ExpectedFunction; 2873 return; 2874 } 2875 2876 D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context)); 2877 } else { 2878 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 2879 } 2880} 2881 2882static void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2883 if (S.LangOpts.CUDA) { 2884 // check the attribute arguments. 2885 if (!checkAttributeNumArgs(S, Attr, 0)) 2886 return; 2887 2888 2889 if (!isa<VarDecl>(D)) { 2890 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2891 << Attr.getName() << ExpectedVariable; 2892 return; 2893 } 2894 2895 D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context)); 2896 } else { 2897 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 2898 } 2899} 2900 2901static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2902 // check the attribute arguments. 2903 if (!checkAttributeNumArgs(S, Attr, 0)) 2904 return; 2905 2906 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 2907 if (Fn == 0) { 2908 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2909 << Attr.getName() << ExpectedFunction; 2910 return; 2911 } 2912 2913 if (!Fn->isInlineSpecified()) { 2914 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 2915 return; 2916 } 2917 2918 D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context)); 2919} 2920 2921static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2922 if (hasDeclarator(D)) return; 2923 2924 // Diagnostic is emitted elsewhere: here we store the (valid) Attr 2925 // in the Decl node for syntactic reasoning, e.g., pretty-printing. 2926 CallingConv CC; 2927 if (S.CheckCallingConvAttr(Attr, CC)) 2928 return; 2929 2930 if (!isa<ObjCMethodDecl>(D)) { 2931 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2932 << Attr.getName() << ExpectedFunctionOrMethod; 2933 return; 2934 } 2935 2936 switch (Attr.getKind()) { 2937 case AttributeList::AT_fastcall: 2938 D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context)); 2939 return; 2940 case AttributeList::AT_stdcall: 2941 D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context)); 2942 return; 2943 case AttributeList::AT_thiscall: 2944 D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context)); 2945 return; 2946 case AttributeList::AT_cdecl: 2947 D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context)); 2948 return; 2949 case AttributeList::AT_pascal: 2950 D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context)); 2951 return; 2952 case AttributeList::AT_pcs: { 2953 Expr *Arg = Attr.getArg(0); 2954 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 2955 if (!Str || !Str->isAscii()) { 2956 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 2957 << "pcs" << 1; 2958 Attr.setInvalid(); 2959 return; 2960 } 2961 2962 StringRef StrRef = Str->getString(); 2963 PcsAttr::PCSType PCS; 2964 if (StrRef == "aapcs") 2965 PCS = PcsAttr::AAPCS; 2966 else if (StrRef == "aapcs-vfp") 2967 PCS = PcsAttr::AAPCS_VFP; 2968 else { 2969 S.Diag(Attr.getLoc(), diag::err_invalid_pcs); 2970 Attr.setInvalid(); 2971 return; 2972 } 2973 2974 D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS)); 2975 } 2976 default: 2977 llvm_unreachable("unexpected attribute kind"); 2978 return; 2979 } 2980} 2981 2982static void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){ 2983 assert(!Attr.isInvalid()); 2984 D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context)); 2985} 2986 2987bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 2988 if (attr.isInvalid()) 2989 return true; 2990 2991 if ((attr.getNumArgs() != 0 && 2992 !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) || 2993 attr.getParameterName()) { 2994 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2995 attr.setInvalid(); 2996 return true; 2997 } 2998 2999 // TODO: diagnose uses of these conventions on the wrong target. Or, better 3000 // move to TargetAttributesSema one day. 3001 switch (attr.getKind()) { 3002 case AttributeList::AT_cdecl: CC = CC_C; break; 3003 case AttributeList::AT_fastcall: CC = CC_X86FastCall; break; 3004 case AttributeList::AT_stdcall: CC = CC_X86StdCall; break; 3005 case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break; 3006 case AttributeList::AT_pascal: CC = CC_X86Pascal; break; 3007 case AttributeList::AT_pcs: { 3008 Expr *Arg = attr.getArg(0); 3009 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3010 if (!Str || !Str->isAscii()) { 3011 Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string) 3012 << "pcs" << 1; 3013 attr.setInvalid(); 3014 return true; 3015 } 3016 3017 StringRef StrRef = Str->getString(); 3018 if (StrRef == "aapcs") { 3019 CC = CC_AAPCS; 3020 break; 3021 } else if (StrRef == "aapcs-vfp") { 3022 CC = CC_AAPCS_VFP; 3023 break; 3024 } 3025 // FALLS THROUGH 3026 } 3027 default: llvm_unreachable("unexpected attribute kind"); return true; 3028 } 3029 3030 return false; 3031} 3032 3033static void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3034 if (hasDeclarator(D)) return; 3035 3036 unsigned numParams; 3037 if (S.CheckRegparmAttr(Attr, numParams)) 3038 return; 3039 3040 if (!isa<ObjCMethodDecl>(D)) { 3041 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3042 << Attr.getName() << ExpectedFunctionOrMethod; 3043 return; 3044 } 3045 3046 D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams)); 3047} 3048 3049/// Checks a regparm attribute, returning true if it is ill-formed and 3050/// otherwise setting numParams to the appropriate value. 3051bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { 3052 if (Attr.isInvalid()) 3053 return true; 3054 3055 if (Attr.getNumArgs() != 1) { 3056 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 3057 Attr.setInvalid(); 3058 return true; 3059 } 3060 3061 Expr *NumParamsExpr = Attr.getArg(0); 3062 llvm::APSInt NumParams(32); 3063 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 3064 !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 3065 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 3066 << "regparm" << NumParamsExpr->getSourceRange(); 3067 Attr.setInvalid(); 3068 return true; 3069 } 3070 3071 if (Context.getTargetInfo().getRegParmMax() == 0) { 3072 Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 3073 << NumParamsExpr->getSourceRange(); 3074 Attr.setInvalid(); 3075 return true; 3076 } 3077 3078 numParams = NumParams.getZExtValue(); 3079 if (numParams > Context.getTargetInfo().getRegParmMax()) { 3080 Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 3081 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 3082 Attr.setInvalid(); 3083 return true; 3084 } 3085 3086 return false; 3087} 3088 3089static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ 3090 if (S.LangOpts.CUDA) { 3091 // check the attribute arguments. 3092 if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 3093 // FIXME: 0 is not okay. 3094 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 3095 return; 3096 } 3097 3098 if (!isFunctionOrMethod(D)) { 3099 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3100 << Attr.getName() << ExpectedFunctionOrMethod; 3101 return; 3102 } 3103 3104 Expr *MaxThreadsExpr = Attr.getArg(0); 3105 llvm::APSInt MaxThreads(32); 3106 if (MaxThreadsExpr->isTypeDependent() || 3107 MaxThreadsExpr->isValueDependent() || 3108 !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 3109 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 3110 << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 3111 return; 3112 } 3113 3114 llvm::APSInt MinBlocks(32); 3115 if (Attr.getNumArgs() > 1) { 3116 Expr *MinBlocksExpr = Attr.getArg(1); 3117 if (MinBlocksExpr->isTypeDependent() || 3118 MinBlocksExpr->isValueDependent() || 3119 !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 3120 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 3121 << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 3122 return; 3123 } 3124 } 3125 3126 D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context, 3127 MaxThreads.getZExtValue(), 3128 MinBlocks.getZExtValue())); 3129 } else { 3130 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 3131 } 3132} 3133 3134//===----------------------------------------------------------------------===// 3135// Checker-specific attribute handlers. 3136//===----------------------------------------------------------------------===// 3137 3138static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 3139 return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type); 3140} 3141static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 3142 return type->isPointerType() || isValidSubjectOfNSAttribute(S, type); 3143} 3144 3145static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3146 ParmVarDecl *param = dyn_cast<ParmVarDecl>(D); 3147 if (!param) { 3148 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3149 << Attr.getRange() << Attr.getName() << ExpectedParameter; 3150 return; 3151 } 3152 3153 bool typeOK, cf; 3154 if (Attr.getKind() == AttributeList::AT_ns_consumed) { 3155 typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 3156 cf = false; 3157 } else { 3158 typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 3159 cf = true; 3160 } 3161 3162 if (!typeOK) { 3163 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 3164 << Attr.getRange() << Attr.getName() << cf; 3165 return; 3166 } 3167 3168 if (cf) 3169 param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context)); 3170 else 3171 param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context)); 3172} 3173 3174static void handleNSConsumesSelfAttr(Sema &S, Decl *D, 3175 const AttributeList &Attr) { 3176 if (!isa<ObjCMethodDecl>(D)) { 3177 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3178 << Attr.getRange() << Attr.getName() << ExpectedMethod; 3179 return; 3180 } 3181 3182 D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context)); 3183} 3184 3185static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 3186 const AttributeList &Attr) { 3187 3188 QualType returnType; 3189 3190 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 3191 returnType = MD->getResultType(); 3192 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 3193 returnType = PD->getType(); 3194 else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) && 3195 (Attr.getKind() == AttributeList::AT_ns_returns_retained)) 3196 return; // ignore: was handled as a type attribute 3197 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 3198 returnType = FD->getResultType(); 3199 else { 3200 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3201 << Attr.getRange() << Attr.getName() 3202 << ExpectedFunctionOrMethod; 3203 return; 3204 } 3205 3206 bool typeOK; 3207 bool cf; 3208 switch (Attr.getKind()) { 3209 default: llvm_unreachable("invalid ownership attribute"); return; 3210 case AttributeList::AT_ns_returns_autoreleased: 3211 case AttributeList::AT_ns_returns_retained: 3212 case AttributeList::AT_ns_returns_not_retained: 3213 typeOK = isValidSubjectOfNSAttribute(S, returnType); 3214 cf = false; 3215 break; 3216 3217 case AttributeList::AT_cf_returns_retained: 3218 case AttributeList::AT_cf_returns_not_retained: 3219 typeOK = isValidSubjectOfCFAttribute(S, returnType); 3220 cf = true; 3221 break; 3222 } 3223 3224 if (!typeOK) { 3225 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3226 << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf; 3227 return; 3228 } 3229 3230 switch (Attr.getKind()) { 3231 default: 3232 llvm_unreachable("invalid ownership attribute"); 3233 case AttributeList::AT_ns_returns_autoreleased: 3234 D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(), 3235 S.Context)); 3236 return; 3237 case AttributeList::AT_cf_returns_not_retained: 3238 D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(), 3239 S.Context)); 3240 return; 3241 case AttributeList::AT_ns_returns_not_retained: 3242 D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(), 3243 S.Context)); 3244 return; 3245 case AttributeList::AT_cf_returns_retained: 3246 D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(), 3247 S.Context)); 3248 return; 3249 case AttributeList::AT_ns_returns_retained: 3250 D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(), 3251 S.Context)); 3252 return; 3253 }; 3254} 3255 3256static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, 3257 const AttributeList &attr) { 3258 SourceLocation loc = attr.getLoc(); 3259 3260 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); 3261 3262 if (!isa<ObjCMethodDecl>(method)) { 3263 S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type) 3264 << SourceRange(loc, loc) << attr.getName() << 13 /* methods */; 3265 return; 3266 } 3267 3268 // Check that the method returns a normal pointer. 3269 QualType resultType = method->getResultType(); 3270 3271 if (!resultType->isReferenceType() && 3272 (!resultType->isPointerType() || resultType->isObjCRetainableType())) { 3273 S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3274 << SourceRange(loc) 3275 << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2; 3276 3277 // Drop the attribute. 3278 return; 3279 } 3280 3281 method->addAttr( 3282 ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context)); 3283} 3284 3285/// Handle cf_audited_transfer and cf_unknown_transfer. 3286static void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) { 3287 if (!isa<FunctionDecl>(D)) { 3288 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3289 << A.getRange() << A.getName() << 0 /*function*/; 3290 return; 3291 } 3292 3293 bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer); 3294 3295 // Check whether there's a conflicting attribute already present. 3296 Attr *Existing; 3297 if (IsAudited) { 3298 Existing = D->getAttr<CFUnknownTransferAttr>(); 3299 } else { 3300 Existing = D->getAttr<CFAuditedTransferAttr>(); 3301 } 3302 if (Existing) { 3303 S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible) 3304 << A.getName() 3305 << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer") 3306 << A.getRange() << Existing->getRange(); 3307 return; 3308 } 3309 3310 // All clear; add the attribute. 3311 if (IsAudited) { 3312 D->addAttr( 3313 ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context)); 3314 } else { 3315 D->addAttr( 3316 ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context)); 3317 } 3318} 3319 3320static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, 3321 const AttributeList &Attr) { 3322 RecordDecl *RD = dyn_cast<RecordDecl>(D); 3323 if (!RD || RD->isUnion()) { 3324 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3325 << Attr.getRange() << Attr.getName() << 14 /*struct */; 3326 } 3327 3328 IdentifierInfo *ParmName = Attr.getParameterName(); 3329 3330 // In Objective-C, verify that the type names an Objective-C type. 3331 // We don't want to check this outside of ObjC because people sometimes 3332 // do crazy C declarations of Objective-C types. 3333 if (ParmName && S.getLangOptions().ObjC1) { 3334 // Check for an existing type with this name. 3335 LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(), 3336 Sema::LookupOrdinaryName); 3337 if (S.LookupName(R, Sc)) { 3338 NamedDecl *Target = R.getFoundDecl(); 3339 if (Target && !isa<ObjCInterfaceDecl>(Target)) { 3340 S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface); 3341 S.Diag(Target->getLocStart(), diag::note_declared_at); 3342 } 3343 } 3344 } 3345 3346 D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context, 3347 ParmName)); 3348} 3349 3350static void handleObjCOwnershipAttr(Sema &S, Decl *D, 3351 const AttributeList &Attr) { 3352 if (hasDeclarator(D)) return; 3353 3354 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3355 << Attr.getRange() << Attr.getName() << 12 /* variable */; 3356} 3357 3358static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 3359 const AttributeList &Attr) { 3360 if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) { 3361 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3362 << Attr.getRange() << Attr.getName() << 12 /* variable */; 3363 return; 3364 } 3365 3366 ValueDecl *vd = cast<ValueDecl>(D); 3367 QualType type = vd->getType(); 3368 3369 if (!type->isDependentType() && 3370 !type->isObjCLifetimeType()) { 3371 S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 3372 << type; 3373 return; 3374 } 3375 3376 Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 3377 3378 // If we have no lifetime yet, check the lifetime we're presumably 3379 // going to infer. 3380 if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 3381 lifetime = type->getObjCARCImplicitLifetime(); 3382 3383 switch (lifetime) { 3384 case Qualifiers::OCL_None: 3385 assert(type->isDependentType() && 3386 "didn't infer lifetime for non-dependent type?"); 3387 break; 3388 3389 case Qualifiers::OCL_Weak: // meaningful 3390 case Qualifiers::OCL_Strong: // meaningful 3391 break; 3392 3393 case Qualifiers::OCL_ExplicitNone: 3394 case Qualifiers::OCL_Autoreleasing: 3395 S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 3396 << (lifetime == Qualifiers::OCL_Autoreleasing); 3397 break; 3398 } 3399 3400 D->addAttr(::new (S.Context) 3401 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context)); 3402} 3403 3404static bool isKnownDeclSpecAttr(const AttributeList &Attr) { 3405 return Attr.getKind() == AttributeList::AT_dllimport || 3406 Attr.getKind() == AttributeList::AT_dllexport || 3407 Attr.getKind() == AttributeList::AT_uuid; 3408} 3409 3410//===----------------------------------------------------------------------===// 3411// Microsoft specific attribute handlers. 3412//===----------------------------------------------------------------------===// 3413 3414static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3415 if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) { 3416 // check the attribute arguments. 3417 if (!checkAttributeNumArgs(S, Attr, 1)) 3418 return; 3419 3420 Expr *Arg = Attr.getArg(0); 3421 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3422 if (!Str || !Str->isAscii()) { 3423 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3424 << "uuid" << 1; 3425 return; 3426 } 3427 3428 StringRef StrRef = Str->getString(); 3429 3430 bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 3431 StrRef.back() == '}'; 3432 3433 // Validate GUID length. 3434 if (IsCurly && StrRef.size() != 38) { 3435 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3436 return; 3437 } 3438 if (!IsCurly && StrRef.size() != 36) { 3439 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3440 return; 3441 } 3442 3443 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 3444 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 3445 StringRef::iterator I = StrRef.begin(); 3446 if (IsCurly) // Skip the optional '{' 3447 ++I; 3448 3449 for (int i = 0; i < 36; ++i) { 3450 if (i == 8 || i == 13 || i == 18 || i == 23) { 3451 if (*I != '-') { 3452 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3453 return; 3454 } 3455 } else if (!isxdigit(*I)) { 3456 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3457 return; 3458 } 3459 I++; 3460 } 3461 3462 D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, 3463 Str->getString())); 3464 } else 3465 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 3466} 3467 3468//===----------------------------------------------------------------------===// 3469// Top Level Sema Entry Points 3470//===----------------------------------------------------------------------===// 3471 3472static void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 3473 const AttributeList &Attr) { 3474 switch (Attr.getKind()) { 3475 case AttributeList::AT_device: handleDeviceAttr (S, D, Attr); break; 3476 case AttributeList::AT_host: handleHostAttr (S, D, Attr); break; 3477 case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break; 3478 default: 3479 break; 3480 } 3481} 3482 3483static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 3484 const AttributeList &Attr) { 3485 switch (Attr.getKind()) { 3486 case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break; 3487 case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break; 3488 case AttributeList::AT_IBOutletCollection: 3489 handleIBOutletCollection(S, D, Attr); break; 3490 case AttributeList::AT_address_space: 3491 case AttributeList::AT_opencl_image_access: 3492 case AttributeList::AT_objc_gc: 3493 case AttributeList::AT_vector_size: 3494 case AttributeList::AT_neon_vector_type: 3495 case AttributeList::AT_neon_polyvector_type: 3496 // Ignore these, these are type attributes, handled by 3497 // ProcessTypeAttributes. 3498 break; 3499 case AttributeList::AT_device: 3500 case AttributeList::AT_host: 3501 case AttributeList::AT_overloadable: 3502 // Ignore, this is a non-inheritable attribute, handled 3503 // by ProcessNonInheritableDeclAttr. 3504 break; 3505 case AttributeList::AT_alias: handleAliasAttr (S, D, Attr); break; 3506 case AttributeList::AT_aligned: handleAlignedAttr (S, D, Attr); break; 3507 case AttributeList::AT_always_inline: 3508 handleAlwaysInlineAttr (S, D, Attr); break; 3509 case AttributeList::AT_analyzer_noreturn: 3510 handleAnalyzerNoReturnAttr (S, D, Attr); break; 3511 case AttributeList::AT_annotate: handleAnnotateAttr (S, D, Attr); break; 3512 case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break; 3513 case AttributeList::AT_carries_dependency: 3514 handleDependencyAttr (S, D, Attr); break; 3515 case AttributeList::AT_common: handleCommonAttr (S, D, Attr); break; 3516 case AttributeList::AT_constant: handleConstantAttr (S, D, Attr); break; 3517 case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break; 3518 case AttributeList::AT_deprecated: handleDeprecatedAttr (S, D, Attr); break; 3519 case AttributeList::AT_destructor: handleDestructorAttr (S, D, Attr); break; 3520 case AttributeList::AT_ext_vector_type: 3521 handleExtVectorTypeAttr(S, scope, D, Attr); 3522 break; 3523 case AttributeList::AT_format: handleFormatAttr (S, D, Attr); break; 3524 case AttributeList::AT_format_arg: handleFormatArgAttr (S, D, Attr); break; 3525 case AttributeList::AT_global: handleGlobalAttr (S, D, Attr); break; 3526 case AttributeList::AT_gnu_inline: handleGNUInlineAttr (S, D, Attr); break; 3527 case AttributeList::AT_launch_bounds: 3528 handleLaunchBoundsAttr(S, D, Attr); 3529 break; 3530 case AttributeList::AT_mode: handleModeAttr (S, D, Attr); break; 3531 case AttributeList::AT_malloc: handleMallocAttr (S, D, Attr); break; 3532 case AttributeList::AT_may_alias: handleMayAliasAttr (S, D, Attr); break; 3533 case AttributeList::AT_nocommon: handleNoCommonAttr (S, D, Attr); break; 3534 case AttributeList::AT_nonnull: handleNonNullAttr (S, D, Attr); break; 3535 case AttributeList::AT_ownership_returns: 3536 case AttributeList::AT_ownership_takes: 3537 case AttributeList::AT_ownership_holds: 3538 handleOwnershipAttr (S, D, Attr); break; 3539 case AttributeList::AT_naked: handleNakedAttr (S, D, Attr); break; 3540 case AttributeList::AT_noreturn: handleNoReturnAttr (S, D, Attr); break; 3541 case AttributeList::AT_nothrow: handleNothrowAttr (S, D, Attr); break; 3542 case AttributeList::AT_shared: handleSharedAttr (S, D, Attr); break; 3543 case AttributeList::AT_vecreturn: handleVecReturnAttr (S, D, Attr); break; 3544 3545 case AttributeList::AT_objc_ownership: 3546 handleObjCOwnershipAttr(S, D, Attr); break; 3547 case AttributeList::AT_objc_precise_lifetime: 3548 handleObjCPreciseLifetimeAttr(S, D, Attr); break; 3549 3550 case AttributeList::AT_objc_returns_inner_pointer: 3551 handleObjCReturnsInnerPointerAttr(S, D, Attr); break; 3552 3553 case AttributeList::AT_ns_bridged: 3554 handleNSBridgedAttr(S, scope, D, Attr); break; 3555 3556 case AttributeList::AT_cf_audited_transfer: 3557 case AttributeList::AT_cf_unknown_transfer: 3558 handleCFTransferAttr(S, D, Attr); break; 3559 3560 // Checker-specific. 3561 case AttributeList::AT_cf_consumed: 3562 case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break; 3563 case AttributeList::AT_ns_consumes_self: 3564 handleNSConsumesSelfAttr(S, D, Attr); break; 3565 3566 case AttributeList::AT_ns_returns_autoreleased: 3567 case AttributeList::AT_ns_returns_not_retained: 3568 case AttributeList::AT_cf_returns_not_retained: 3569 case AttributeList::AT_ns_returns_retained: 3570 case AttributeList::AT_cf_returns_retained: 3571 handleNSReturnsRetainedAttr(S, D, Attr); break; 3572 3573 case AttributeList::AT_reqd_wg_size: 3574 handleReqdWorkGroupSize(S, D, Attr); break; 3575 3576 case AttributeList::AT_init_priority: 3577 handleInitPriorityAttr(S, D, Attr); break; 3578 3579 case AttributeList::AT_packed: handlePackedAttr (S, D, Attr); break; 3580 case AttributeList::AT_MsStruct: handleMsStructAttr (S, D, Attr); break; 3581 case AttributeList::AT_section: handleSectionAttr (S, D, Attr); break; 3582 case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break; 3583 case AttributeList::AT_arc_weakref_unavailable: 3584 handleArcWeakrefUnavailableAttr (S, D, Attr); 3585 break; 3586 case AttributeList::AT_unused: handleUnusedAttr (S, D, Attr); break; 3587 case AttributeList::AT_returns_twice: 3588 handleReturnsTwiceAttr(S, D, Attr); 3589 break; 3590 case AttributeList::AT_used: handleUsedAttr (S, D, Attr); break; 3591 case AttributeList::AT_visibility: handleVisibilityAttr (S, D, Attr); break; 3592 case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr); 3593 break; 3594 case AttributeList::AT_weak: handleWeakAttr (S, D, Attr); break; 3595 case AttributeList::AT_weakref: handleWeakRefAttr (S, D, Attr); break; 3596 case AttributeList::AT_weak_import: handleWeakImportAttr (S, D, Attr); break; 3597 case AttributeList::AT_transparent_union: 3598 handleTransparentUnionAttr(S, D, Attr); 3599 break; 3600 case AttributeList::AT_objc_exception: 3601 handleObjCExceptionAttr(S, D, Attr); 3602 break; 3603 case AttributeList::AT_objc_method_family: 3604 handleObjCMethodFamilyAttr(S, D, Attr); 3605 break; 3606 case AttributeList::AT_nsobject: handleObjCNSObject (S, D, Attr); break; 3607 case AttributeList::AT_blocks: handleBlocksAttr (S, D, Attr); break; 3608 case AttributeList::AT_sentinel: handleSentinelAttr (S, D, Attr); break; 3609 case AttributeList::AT_const: handleConstAttr (S, D, Attr); break; 3610 case AttributeList::AT_pure: handlePureAttr (S, D, Attr); break; 3611 case AttributeList::AT_cleanup: handleCleanupAttr (S, D, Attr); break; 3612 case AttributeList::AT_nodebug: handleNoDebugAttr (S, D, Attr); break; 3613 case AttributeList::AT_noinline: handleNoInlineAttr (S, D, Attr); break; 3614 case AttributeList::AT_regparm: handleRegparmAttr (S, D, Attr); break; 3615 case AttributeList::IgnoredAttribute: 3616 // Just ignore 3617 break; 3618 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 3619 handleNoInstrumentFunctionAttr(S, D, Attr); 3620 break; 3621 case AttributeList::AT_stdcall: 3622 case AttributeList::AT_cdecl: 3623 case AttributeList::AT_fastcall: 3624 case AttributeList::AT_thiscall: 3625 case AttributeList::AT_pascal: 3626 case AttributeList::AT_pcs: 3627 handleCallConvAttr(S, D, Attr); 3628 break; 3629 case AttributeList::AT_opencl_kernel_function: 3630 handleOpenCLKernelAttr(S, D, Attr); 3631 break; 3632 case AttributeList::AT_uuid: 3633 handleUuidAttr(S, D, Attr); 3634 break; 3635 3636 // Thread safety attributes: 3637 case AttributeList::AT_guarded_var: 3638 handleGuardedVarAttr(S, D, Attr); 3639 break; 3640 case AttributeList::AT_pt_guarded_var: 3641 handleGuardedVarAttr(S, D, Attr, /*pointer = */true); 3642 break; 3643 case AttributeList::AT_scoped_lockable: 3644 handleLockableAttr(S, D, Attr, /*scoped = */true); 3645 break; 3646 case AttributeList::AT_no_thread_safety_analysis: 3647 handleNoThreadSafetyAttr(S, D, Attr); 3648 break; 3649 case AttributeList::AT_lockable: 3650 handleLockableAttr(S, D, Attr); 3651 break; 3652 case AttributeList::AT_guarded_by: 3653 handleGuardedByAttr(S, D, Attr); 3654 break; 3655 case AttributeList::AT_pt_guarded_by: 3656 handleGuardedByAttr(S, D, Attr, /*pointer = */true); 3657 break; 3658 case AttributeList::AT_exclusive_lock_function: 3659 handleLockFunAttr(S, D, Attr, /*exclusive = */true); 3660 break; 3661 case AttributeList::AT_exclusive_locks_required: 3662 handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true); 3663 break; 3664 case AttributeList::AT_exclusive_trylock_function: 3665 handleTrylockFunAttr(S, D, Attr, /*exclusive = */true); 3666 break; 3667 case AttributeList::AT_lock_returned: 3668 handleLockReturnedAttr(S, D, Attr); 3669 break; 3670 case AttributeList::AT_locks_excluded: 3671 handleLocksExcludedAttr(S, D, Attr); 3672 break; 3673 case AttributeList::AT_shared_lock_function: 3674 handleLockFunAttr(S, D, Attr); 3675 break; 3676 case AttributeList::AT_shared_locks_required: 3677 handleLocksRequiredAttr(S, D, Attr); 3678 break; 3679 case AttributeList::AT_shared_trylock_function: 3680 handleTrylockFunAttr(S, D, Attr); 3681 break; 3682 case AttributeList::AT_unlock_function: 3683 handleUnlockFunAttr(S, D, Attr); 3684 break; 3685 case AttributeList::AT_acquired_before: 3686 handleAcquireOrderAttr(S, D, Attr, /*before = */true); 3687 break; 3688 case AttributeList::AT_acquired_after: 3689 handleAcquireOrderAttr(S, D, Attr, /*before = */false); 3690 break; 3691 3692 default: 3693 // Ask target about the attribute. 3694 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 3695 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 3696 S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 3697 << Attr.getName(); 3698 break; 3699 } 3700} 3701 3702/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 3703/// the attribute applies to decls. If the attribute is a type attribute, just 3704/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 3705/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 3706static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 3707 const AttributeList &Attr, 3708 bool NonInheritable, bool Inheritable) { 3709 if (Attr.isInvalid()) 3710 return; 3711 3712 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 3713 // FIXME: Try to deal with other __declspec attributes! 3714 return; 3715 3716 if (NonInheritable) 3717 ProcessNonInheritableDeclAttr(S, scope, D, Attr); 3718 3719 if (Inheritable) 3720 ProcessInheritableDeclAttr(S, scope, D, Attr); 3721} 3722 3723/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 3724/// attribute list to the specified decl, ignoring any type attributes. 3725void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 3726 const AttributeList *AttrList, 3727 bool NonInheritable, bool Inheritable) { 3728 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 3729 ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable); 3730 } 3731 3732 // GCC accepts 3733 // static int a9 __attribute__((weakref)); 3734 // but that looks really pointless. We reject it. 3735 if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 3736 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 3737 dyn_cast<NamedDecl>(D)->getNameAsString(); 3738 return; 3739 } 3740} 3741 3742/// checkUnusedDeclAttributes - Check a list of attributes to see if it 3743/// contains any decl attributes that we should warn about. 3744static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) { 3745 for ( ; A; A = A->getNext()) { 3746 // Only warn if the attribute is an unignored, non-type attribute. 3747 if (A->isUsedAsTypeAttr()) continue; 3748 if (A->getKind() == AttributeList::IgnoredAttribute) continue; 3749 3750 if (A->getKind() == AttributeList::UnknownAttribute) { 3751 S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored) 3752 << A->getName() << A->getRange(); 3753 } else { 3754 S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl) 3755 << A->getName() << A->getRange(); 3756 } 3757 } 3758} 3759 3760/// checkUnusedDeclAttributes - Given a declarator which is not being 3761/// used to build a declaration, complain about any decl attributes 3762/// which might be lying around on it. 3763void Sema::checkUnusedDeclAttributes(Declarator &D) { 3764 ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList()); 3765 ::checkUnusedDeclAttributes(*this, D.getAttributes()); 3766 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) 3767 ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs()); 3768} 3769 3770/// DeclClonePragmaWeak - clone existing decl (maybe definition), 3771/// #pragma weak needs a non-definition decl and source may not have one 3772NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 3773 SourceLocation Loc) { 3774 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 3775 NamedDecl *NewD = 0; 3776 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 3777 FunctionDecl *NewFD; 3778 // FIXME: Missing call to CheckFunctionDeclaration(). 3779 // FIXME: Mangling? 3780 // FIXME: Is the qualifier info correct? 3781 // FIXME: Is the DeclContext correct? 3782 NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 3783 Loc, Loc, DeclarationName(II), 3784 FD->getType(), FD->getTypeSourceInfo(), 3785 SC_None, SC_None, 3786 false/*isInlineSpecified*/, 3787 FD->hasPrototype(), 3788 false/*isConstexprSpecified*/); 3789 NewD = NewFD; 3790 3791 if (FD->getQualifier()) 3792 NewFD->setQualifierInfo(FD->getQualifierLoc()); 3793 3794 // Fake up parameter variables; they are declared as if this were 3795 // a typedef. 3796 QualType FDTy = FD->getType(); 3797 if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 3798 SmallVector<ParmVarDecl*, 16> Params; 3799 for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), 3800 AE = FT->arg_type_end(); AI != AE; ++AI) { 3801 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI); 3802 Param->setScopeInfo(0, Params.size()); 3803 Params.push_back(Param); 3804 } 3805 NewFD->setParams(Params); 3806 } 3807 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 3808 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 3809 VD->getInnerLocStart(), VD->getLocation(), II, 3810 VD->getType(), VD->getTypeSourceInfo(), 3811 VD->getStorageClass(), 3812 VD->getStorageClassAsWritten()); 3813 if (VD->getQualifier()) { 3814 VarDecl *NewVD = cast<VarDecl>(NewD); 3815 NewVD->setQualifierInfo(VD->getQualifierLoc()); 3816 } 3817 } 3818 return NewD; 3819} 3820 3821/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 3822/// applied to it, possibly with an alias. 3823void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 3824 if (W.getUsed()) return; // only do this once 3825 W.setUsed(true); 3826 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 3827 IdentifierInfo *NDId = ND->getIdentifier(); 3828 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 3829 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 3830 NDId->getName())); 3831 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3832 WeakTopLevelDecl.push_back(NewD); 3833 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 3834 // to insert Decl at TU scope, sorry. 3835 DeclContext *SavedContext = CurContext; 3836 CurContext = Context.getTranslationUnitDecl(); 3837 PushOnScopeChains(NewD, S); 3838 CurContext = SavedContext; 3839 } else { // just add weak to existing 3840 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3841 } 3842} 3843 3844/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 3845/// it, apply them to D. This is a bit tricky because PD can have attributes 3846/// specified in many different places, and we need to find and apply them all. 3847void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 3848 bool NonInheritable, bool Inheritable) { 3849 // It's valid to "forward-declare" #pragma weak, in which case we 3850 // have to do this. 3851 if (Inheritable) { 3852 LoadExternalWeakUndeclaredIdentifiers(); 3853 if (!WeakUndeclaredIdentifiers.empty()) { 3854 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 3855 if (IdentifierInfo *Id = ND->getIdentifier()) { 3856 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 3857 = WeakUndeclaredIdentifiers.find(Id); 3858 if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 3859 WeakInfo W = I->second; 3860 DeclApplyPragmaWeak(S, ND, W); 3861 WeakUndeclaredIdentifiers[Id] = W; 3862 } 3863 } 3864 } 3865 } 3866 } 3867 3868 // Apply decl attributes from the DeclSpec if present. 3869 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 3870 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3871 3872 // Walk the declarator structure, applying decl attributes that were in a type 3873 // position to the decl itself. This handles cases like: 3874 // int *__attr__(x)** D; 3875 // when X is a decl attribute. 3876 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 3877 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 3878 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3879 3880 // Finally, apply any attributes on the decl itself. 3881 if (const AttributeList *Attrs = PD.getAttributes()) 3882 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3883} 3884 3885/// Is the given declaration allowed to use a forbidden type? 3886static bool isForbiddenTypeAllowed(Sema &S, Decl *decl) { 3887 // Private ivars are always okay. Unfortunately, people don't 3888 // always properly make their ivars private, even in system headers. 3889 // Plus we need to make fields okay, too. 3890 // Function declarations in sys headers will be marked unavailable. 3891 if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) && 3892 !isa<FunctionDecl>(decl)) 3893 return false; 3894 3895 // Require it to be declared in a system header. 3896 return S.Context.getSourceManager().isInSystemHeader(decl->getLocation()); 3897} 3898 3899/// Handle a delayed forbidden-type diagnostic. 3900static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 3901 Decl *decl) { 3902 if (decl && isForbiddenTypeAllowed(S, decl)) { 3903 decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context, 3904 "this system declaration uses an unsupported type")); 3905 return; 3906 } 3907 if (S.getLangOptions().ObjCAutoRefCount) 3908 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) { 3909 // FIXME. we may want to supress diagnostics for all 3910 // kind of forbidden type messages on unavailable functions. 3911 if (FD->hasAttr<UnavailableAttr>() && 3912 diag.getForbiddenTypeDiagnostic() == 3913 diag::err_arc_array_param_no_ownership) { 3914 diag.Triggered = true; 3915 return; 3916 } 3917 } 3918 3919 S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 3920 << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 3921 diag.Triggered = true; 3922} 3923 3924// This duplicates a vector push_back but hides the need to know the 3925// size of the type. 3926void Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) { 3927 assert(StackSize <= StackCapacity); 3928 3929 // Grow the stack if necessary. 3930 if (StackSize == StackCapacity) { 3931 unsigned newCapacity = 2 * StackCapacity + 2; 3932 char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)]; 3933 const char *oldBuffer = (const char*) Stack; 3934 3935 if (StackCapacity) 3936 memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic)); 3937 3938 delete[] oldBuffer; 3939 Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer); 3940 StackCapacity = newCapacity; 3941 } 3942 3943 assert(StackSize < StackCapacity); 3944 new (&Stack[StackSize++]) DelayedDiagnostic(diag); 3945} 3946 3947void Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state, 3948 Decl *decl) { 3949 DelayedDiagnostics &DD = S.DelayedDiagnostics; 3950 3951 // Check the invariants. 3952 assert(DD.StackSize >= state.SavedStackSize); 3953 assert(state.SavedStackSize >= DD.ActiveStackBase); 3954 assert(DD.ParsingDepth > 0); 3955 3956 // Drop the parsing depth. 3957 DD.ParsingDepth--; 3958 3959 // If there are no active diagnostics, we're done. 3960 if (DD.StackSize == DD.ActiveStackBase) 3961 return; 3962 3963 // We only want to actually emit delayed diagnostics when we 3964 // successfully parsed a decl. 3965 if (decl && !decl->isInvalidDecl()) { 3966 // We emit all the active diagnostics, not just those starting 3967 // from the saved state. The idea is this: we get one push for a 3968 // decl spec and another for each declarator; in a decl group like: 3969 // deprecated_typedef foo, *bar, baz(); 3970 // only the declarator pops will be passed decls. This is correct; 3971 // we really do need to consider delayed diagnostics from the decl spec 3972 // for each of the different declarations. 3973 for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) { 3974 DelayedDiagnostic &diag = DD.Stack[i]; 3975 if (diag.Triggered) 3976 continue; 3977 3978 switch (diag.Kind) { 3979 case DelayedDiagnostic::Deprecation: 3980 S.HandleDelayedDeprecationCheck(diag, decl); 3981 break; 3982 3983 case DelayedDiagnostic::Access: 3984 S.HandleDelayedAccessCheck(diag, decl); 3985 break; 3986 3987 case DelayedDiagnostic::ForbiddenType: 3988 handleDelayedForbiddenType(S, diag, decl); 3989 break; 3990 } 3991 } 3992 } 3993 3994 // Destroy all the delayed diagnostics we're about to pop off. 3995 for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i) 3996 DD.Stack[i].Destroy(); 3997 3998 DD.StackSize = state.SavedStackSize; 3999} 4000 4001static bool isDeclDeprecated(Decl *D) { 4002 do { 4003 if (D->isDeprecated()) 4004 return true; 4005 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 4006 return false; 4007} 4008 4009void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 4010 Decl *Ctx) { 4011 if (isDeclDeprecated(Ctx)) 4012 return; 4013 4014 DD.Triggered = true; 4015 if (!DD.getDeprecationMessage().empty()) 4016 Diag(DD.Loc, diag::warn_deprecated_message) 4017 << DD.getDeprecationDecl()->getDeclName() 4018 << DD.getDeprecationMessage(); 4019 else 4020 Diag(DD.Loc, diag::warn_deprecated) 4021 << DD.getDeprecationDecl()->getDeclName(); 4022} 4023 4024void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, 4025 SourceLocation Loc, 4026 const ObjCInterfaceDecl *UnknownObjCClass) { 4027 // Delay if we're currently parsing a declaration. 4028 if (DelayedDiagnostics.shouldDelayDiagnostics()) { 4029 DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message)); 4030 return; 4031 } 4032 4033 // Otherwise, don't warn if our current context is deprecated. 4034 if (isDeclDeprecated(cast<Decl>(getCurLexicalContext()))) 4035 return; 4036 if (!Message.empty()) 4037 Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 4038 << Message; 4039 else { 4040 if (!UnknownObjCClass) 4041 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 4042 else { 4043 Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName(); 4044 Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 4045 } 4046 } 4047} 4048