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