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