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