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