SemaDeclAttr.cpp revision f1e7af36d6673185994b3d1751cf7e9a9a1491b8
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.getRange(), S.Context)); 372 else 373 D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), 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.getRange(), 405 S.Context, Arg)); 406 else 407 D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), 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.getRange(), S.Context)); 426 else 427 D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), 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.getRange(), 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.getRange(), S.Context, 484 StartArg, Size)); 485 else 486 D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), 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.getRange(), 514 S.Context, StartArg, 515 Size)); 516 else 517 D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(), 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.getRange(), 554 S.Context, 555 StartArg, Size)); 556 else 557 D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(), 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.getRange(), 586 S.Context, StartArg, 587 Size)); 588 else 589 D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(),S.Context, 819 QT, Attr.getParameterLoc())); 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.getRange(), 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.getRange(), S.Context, 1178 Str->getString())); 1179 } 1180 1181 D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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->setRange(Attr.getRange()); 2002 } else { 2003 D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), 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->setRange(Attr.getRange()); 2017 } else { 2018 D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), 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->setRange(Attr.getRange()); 2397 return; 2398 } 2399 } 2400 2401 D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), 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.getRange(), 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.getRange(), 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.getRange(), S.Context, true, 0)); 2512 return; 2513 } 2514 2515 S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0)); 2516} 2517 2518void Sema::AddAlignedAttr(SourceRange AttrRange, 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(AttrRange, Context, true, E)); 2522 return; 2523 } 2524 2525 SourceLocation AttrLoc = AttrRange.getBegin(); 2526 // FIXME: Cache the number on the Attr object? 2527 llvm::APSInt Alignment(32); 2528 if (!E->isIntegerConstantExpr(Alignment, Context)) { 2529 Diag(AttrLoc, diag::err_attribute_argument_not_int) 2530 << "aligned" << E->getSourceRange(); 2531 return; 2532 } 2533 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 2534 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 2535 << E->getSourceRange(); 2536 return; 2537 } 2538 2539 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); 2540} 2541 2542void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) { 2543 // FIXME: Cache the number on the Attr object if non-dependent? 2544 // FIXME: Perform checking of type validity 2545 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS)); 2546 return; 2547} 2548 2549/// handleModeAttr - This attribute modifies the width of a decl with primitive 2550/// type. 2551/// 2552/// Despite what would be logical, the mode attribute is a decl attribute, not a 2553/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 2554/// HImode, not an intermediate pointer. 2555static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2556 // This attribute isn't documented, but glibc uses it. It changes 2557 // the width of an int or unsigned int to the specified size. 2558 2559 // Check that there aren't any arguments 2560 if (!checkAttributeNumArgs(S, Attr, 0)) 2561 return; 2562 2563 2564 IdentifierInfo *Name = Attr.getParameterName(); 2565 if (!Name) { 2566 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 2567 return; 2568 } 2569 2570 StringRef Str = Attr.getParameterName()->getName(); 2571 2572 // Normalize the attribute name, __foo__ becomes foo. 2573 if (Str.startswith("__") && Str.endswith("__")) 2574 Str = Str.substr(2, Str.size() - 4); 2575 2576 unsigned DestWidth = 0; 2577 bool IntegerMode = true; 2578 bool ComplexMode = false; 2579 switch (Str.size()) { 2580 case 2: 2581 switch (Str[0]) { 2582 case 'Q': DestWidth = 8; break; 2583 case 'H': DestWidth = 16; break; 2584 case 'S': DestWidth = 32; break; 2585 case 'D': DestWidth = 64; break; 2586 case 'X': DestWidth = 96; break; 2587 case 'T': DestWidth = 128; break; 2588 } 2589 if (Str[1] == 'F') { 2590 IntegerMode = false; 2591 } else if (Str[1] == 'C') { 2592 IntegerMode = false; 2593 ComplexMode = true; 2594 } else if (Str[1] != 'I') { 2595 DestWidth = 0; 2596 } 2597 break; 2598 case 4: 2599 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 2600 // pointer on PIC16 and other embedded platforms. 2601 if (Str == "word") 2602 DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2603 else if (Str == "byte") 2604 DestWidth = S.Context.getTargetInfo().getCharWidth(); 2605 break; 2606 case 7: 2607 if (Str == "pointer") 2608 DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2609 break; 2610 } 2611 2612 QualType OldTy; 2613 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 2614 OldTy = TD->getUnderlyingType(); 2615 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 2616 OldTy = VD->getType(); 2617 else { 2618 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 2619 << "mode" << Attr.getRange(); 2620 return; 2621 } 2622 2623 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 2624 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 2625 else if (IntegerMode) { 2626 if (!OldTy->isIntegralOrEnumerationType()) 2627 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 2628 } else if (ComplexMode) { 2629 if (!OldTy->isComplexType()) 2630 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 2631 } else { 2632 if (!OldTy->isFloatingType()) 2633 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 2634 } 2635 2636 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 2637 // and friends, at least with glibc. 2638 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 2639 // width on unusual platforms. 2640 // FIXME: Make sure floating-point mappings are accurate 2641 // FIXME: Support XF and TF types 2642 QualType NewTy; 2643 switch (DestWidth) { 2644 case 0: 2645 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 2646 return; 2647 default: 2648 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2649 return; 2650 case 8: 2651 if (!IntegerMode) { 2652 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2653 return; 2654 } 2655 if (OldTy->isSignedIntegerType()) 2656 NewTy = S.Context.SignedCharTy; 2657 else 2658 NewTy = S.Context.UnsignedCharTy; 2659 break; 2660 case 16: 2661 if (!IntegerMode) { 2662 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2663 return; 2664 } 2665 if (OldTy->isSignedIntegerType()) 2666 NewTy = S.Context.ShortTy; 2667 else 2668 NewTy = S.Context.UnsignedShortTy; 2669 break; 2670 case 32: 2671 if (!IntegerMode) 2672 NewTy = S.Context.FloatTy; 2673 else if (OldTy->isSignedIntegerType()) 2674 NewTy = S.Context.IntTy; 2675 else 2676 NewTy = S.Context.UnsignedIntTy; 2677 break; 2678 case 64: 2679 if (!IntegerMode) 2680 NewTy = S.Context.DoubleTy; 2681 else if (OldTy->isSignedIntegerType()) 2682 if (S.Context.getTargetInfo().getLongWidth() == 64) 2683 NewTy = S.Context.LongTy; 2684 else 2685 NewTy = S.Context.LongLongTy; 2686 else 2687 if (S.Context.getTargetInfo().getLongWidth() == 64) 2688 NewTy = S.Context.UnsignedLongTy; 2689 else 2690 NewTy = S.Context.UnsignedLongLongTy; 2691 break; 2692 case 96: 2693 NewTy = S.Context.LongDoubleTy; 2694 break; 2695 case 128: 2696 if (!IntegerMode) { 2697 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2698 return; 2699 } 2700 if (OldTy->isSignedIntegerType()) 2701 NewTy = S.Context.Int128Ty; 2702 else 2703 NewTy = S.Context.UnsignedInt128Ty; 2704 break; 2705 } 2706 2707 if (ComplexMode) { 2708 NewTy = S.Context.getComplexType(NewTy); 2709 } 2710 2711 // Install the new type. 2712 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 2713 // FIXME: preserve existing source info. 2714 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 2715 } else 2716 cast<ValueDecl>(D)->setType(NewTy); 2717} 2718 2719static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2720 // check the attribute arguments. 2721 if (!checkAttributeNumArgs(S, Attr, 0)) 2722 return; 2723 2724 if (!isFunctionOrMethod(D)) { 2725 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2726 << Attr.getName() << ExpectedFunction; 2727 return; 2728 } 2729 2730 D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context)); 2731} 2732 2733static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2734 // check the attribute arguments. 2735 if (!checkAttributeNumArgs(S, Attr, 0)) 2736 return; 2737 2738 2739 if (!isa<FunctionDecl>(D)) { 2740 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2741 << Attr.getName() << ExpectedFunction; 2742 return; 2743 } 2744 2745 D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context)); 2746} 2747 2748static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D, 2749 const AttributeList &Attr) { 2750 // check the attribute arguments. 2751 if (!checkAttributeNumArgs(S, Attr, 0)) 2752 return; 2753 2754 2755 if (!isa<FunctionDecl>(D)) { 2756 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2757 << Attr.getName() << ExpectedFunction; 2758 return; 2759 } 2760 2761 D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(), 2762 S.Context)); 2763} 2764 2765static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2766 if (S.LangOpts.CUDA) { 2767 // check the attribute arguments. 2768 if (Attr.hasParameterOrArguments()) { 2769 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2770 return; 2771 } 2772 2773 if (!isa<VarDecl>(D)) { 2774 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2775 << Attr.getName() << ExpectedVariable; 2776 return; 2777 } 2778 2779 D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context)); 2780 } else { 2781 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 2782 } 2783} 2784 2785static void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2786 if (S.LangOpts.CUDA) { 2787 // check the attribute arguments. 2788 if (Attr.getNumArgs() != 0) { 2789 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2790 return; 2791 } 2792 2793 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 2794 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2795 << Attr.getName() << ExpectedVariableOrFunction; 2796 return; 2797 } 2798 2799 D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context)); 2800 } else { 2801 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 2802 } 2803} 2804 2805static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2806 if (S.LangOpts.CUDA) { 2807 // check the attribute arguments. 2808 if (!checkAttributeNumArgs(S, Attr, 0)) 2809 return; 2810 2811 if (!isa<FunctionDecl>(D)) { 2812 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2813 << Attr.getName() << ExpectedFunction; 2814 return; 2815 } 2816 2817 FunctionDecl *FD = cast<FunctionDecl>(D); 2818 if (!FD->getResultType()->isVoidType()) { 2819 TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 2820 if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 2821 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 2822 << FD->getType() 2823 << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 2824 "void"); 2825 } else { 2826 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 2827 << FD->getType(); 2828 } 2829 return; 2830 } 2831 2832 D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context)); 2833 } else { 2834 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 2835 } 2836} 2837 2838static void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2839 if (S.LangOpts.CUDA) { 2840 // check the attribute arguments. 2841 if (!checkAttributeNumArgs(S, Attr, 0)) 2842 return; 2843 2844 2845 if (!isa<FunctionDecl>(D)) { 2846 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2847 << Attr.getName() << ExpectedFunction; 2848 return; 2849 } 2850 2851 D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context)); 2852 } else { 2853 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 2854 } 2855} 2856 2857static void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2858 if (S.LangOpts.CUDA) { 2859 // check the attribute arguments. 2860 if (!checkAttributeNumArgs(S, Attr, 0)) 2861 return; 2862 2863 2864 if (!isa<VarDecl>(D)) { 2865 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2866 << Attr.getName() << ExpectedVariable; 2867 return; 2868 } 2869 2870 D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context)); 2871 } else { 2872 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 2873 } 2874} 2875 2876static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2877 // check the attribute arguments. 2878 if (!checkAttributeNumArgs(S, Attr, 0)) 2879 return; 2880 2881 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 2882 if (Fn == 0) { 2883 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2884 << Attr.getName() << ExpectedFunction; 2885 return; 2886 } 2887 2888 if (!Fn->isInlineSpecified()) { 2889 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 2890 return; 2891 } 2892 2893 D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context)); 2894} 2895 2896static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2897 if (hasDeclarator(D)) return; 2898 2899 // Diagnostic is emitted elsewhere: here we store the (valid) Attr 2900 // in the Decl node for syntactic reasoning, e.g., pretty-printing. 2901 CallingConv CC; 2902 if (S.CheckCallingConvAttr(Attr, CC)) 2903 return; 2904 2905 if (!isa<ObjCMethodDecl>(D)) { 2906 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2907 << Attr.getName() << ExpectedFunctionOrMethod; 2908 return; 2909 } 2910 2911 switch (Attr.getKind()) { 2912 case AttributeList::AT_fastcall: 2913 D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context)); 2914 return; 2915 case AttributeList::AT_stdcall: 2916 D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context)); 2917 return; 2918 case AttributeList::AT_thiscall: 2919 D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context)); 2920 return; 2921 case AttributeList::AT_cdecl: 2922 D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context)); 2923 return; 2924 case AttributeList::AT_pascal: 2925 D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context)); 2926 return; 2927 case AttributeList::AT_pcs: { 2928 Expr *Arg = Attr.getArg(0); 2929 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 2930 if (!Str || !Str->isAscii()) { 2931 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 2932 << "pcs" << 1; 2933 Attr.setInvalid(); 2934 return; 2935 } 2936 2937 StringRef StrRef = Str->getString(); 2938 PcsAttr::PCSType PCS; 2939 if (StrRef == "aapcs") 2940 PCS = PcsAttr::AAPCS; 2941 else if (StrRef == "aapcs-vfp") 2942 PCS = PcsAttr::AAPCS_VFP; 2943 else { 2944 S.Diag(Attr.getLoc(), diag::err_invalid_pcs); 2945 Attr.setInvalid(); 2946 return; 2947 } 2948 2949 D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS)); 2950 } 2951 default: 2952 llvm_unreachable("unexpected attribute kind"); 2953 return; 2954 } 2955} 2956 2957static void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){ 2958 assert(!Attr.isInvalid()); 2959 D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context)); 2960} 2961 2962bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 2963 if (attr.isInvalid()) 2964 return true; 2965 2966 if ((attr.getNumArgs() != 0 && 2967 !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) || 2968 attr.getParameterName()) { 2969 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2970 attr.setInvalid(); 2971 return true; 2972 } 2973 2974 // TODO: diagnose uses of these conventions on the wrong target. Or, better 2975 // move to TargetAttributesSema one day. 2976 switch (attr.getKind()) { 2977 case AttributeList::AT_cdecl: CC = CC_C; break; 2978 case AttributeList::AT_fastcall: CC = CC_X86FastCall; break; 2979 case AttributeList::AT_stdcall: CC = CC_X86StdCall; break; 2980 case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break; 2981 case AttributeList::AT_pascal: CC = CC_X86Pascal; break; 2982 case AttributeList::AT_pcs: { 2983 Expr *Arg = attr.getArg(0); 2984 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 2985 if (!Str || !Str->isAscii()) { 2986 Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string) 2987 << "pcs" << 1; 2988 attr.setInvalid(); 2989 return true; 2990 } 2991 2992 StringRef StrRef = Str->getString(); 2993 if (StrRef == "aapcs") { 2994 CC = CC_AAPCS; 2995 break; 2996 } else if (StrRef == "aapcs-vfp") { 2997 CC = CC_AAPCS_VFP; 2998 break; 2999 } 3000 // FALLS THROUGH 3001 } 3002 default: llvm_unreachable("unexpected attribute kind"); return true; 3003 } 3004 3005 return false; 3006} 3007 3008static void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3009 if (hasDeclarator(D)) return; 3010 3011 unsigned numParams; 3012 if (S.CheckRegparmAttr(Attr, numParams)) 3013 return; 3014 3015 if (!isa<ObjCMethodDecl>(D)) { 3016 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3017 << Attr.getName() << ExpectedFunctionOrMethod; 3018 return; 3019 } 3020 3021 D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams)); 3022} 3023 3024/// Checks a regparm attribute, returning true if it is ill-formed and 3025/// otherwise setting numParams to the appropriate value. 3026bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { 3027 if (Attr.isInvalid()) 3028 return true; 3029 3030 if (Attr.getNumArgs() != 1) { 3031 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 3032 Attr.setInvalid(); 3033 return true; 3034 } 3035 3036 Expr *NumParamsExpr = Attr.getArg(0); 3037 llvm::APSInt NumParams(32); 3038 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 3039 !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 3040 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 3041 << "regparm" << NumParamsExpr->getSourceRange(); 3042 Attr.setInvalid(); 3043 return true; 3044 } 3045 3046 if (Context.getTargetInfo().getRegParmMax() == 0) { 3047 Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 3048 << NumParamsExpr->getSourceRange(); 3049 Attr.setInvalid(); 3050 return true; 3051 } 3052 3053 numParams = NumParams.getZExtValue(); 3054 if (numParams > Context.getTargetInfo().getRegParmMax()) { 3055 Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 3056 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 3057 Attr.setInvalid(); 3058 return true; 3059 } 3060 3061 return false; 3062} 3063 3064static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ 3065 if (S.LangOpts.CUDA) { 3066 // check the attribute arguments. 3067 if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 3068 // FIXME: 0 is not okay. 3069 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 3070 return; 3071 } 3072 3073 if (!isFunctionOrMethod(D)) { 3074 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3075 << Attr.getName() << ExpectedFunctionOrMethod; 3076 return; 3077 } 3078 3079 Expr *MaxThreadsExpr = Attr.getArg(0); 3080 llvm::APSInt MaxThreads(32); 3081 if (MaxThreadsExpr->isTypeDependent() || 3082 MaxThreadsExpr->isValueDependent() || 3083 !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 3084 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 3085 << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 3086 return; 3087 } 3088 3089 llvm::APSInt MinBlocks(32); 3090 if (Attr.getNumArgs() > 1) { 3091 Expr *MinBlocksExpr = Attr.getArg(1); 3092 if (MinBlocksExpr->isTypeDependent() || 3093 MinBlocksExpr->isValueDependent() || 3094 !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 3095 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 3096 << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 3097 return; 3098 } 3099 } 3100 3101 D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context, 3102 MaxThreads.getZExtValue(), 3103 MinBlocks.getZExtValue())); 3104 } else { 3105 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 3106 } 3107} 3108 3109//===----------------------------------------------------------------------===// 3110// Checker-specific attribute handlers. 3111//===----------------------------------------------------------------------===// 3112 3113static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 3114 return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type); 3115} 3116static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 3117 return type->isPointerType() || isValidSubjectOfNSAttribute(S, type); 3118} 3119 3120static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3121 ParmVarDecl *param = dyn_cast<ParmVarDecl>(D); 3122 if (!param) { 3123 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3124 << Attr.getRange() << Attr.getName() << ExpectedParameter; 3125 return; 3126 } 3127 3128 bool typeOK, cf; 3129 if (Attr.getKind() == AttributeList::AT_ns_consumed) { 3130 typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 3131 cf = false; 3132 } else { 3133 typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 3134 cf = true; 3135 } 3136 3137 if (!typeOK) { 3138 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 3139 << Attr.getRange() << Attr.getName() << cf; 3140 return; 3141 } 3142 3143 if (cf) 3144 param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context)); 3145 else 3146 param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context)); 3147} 3148 3149static void handleNSConsumesSelfAttr(Sema &S, Decl *D, 3150 const AttributeList &Attr) { 3151 if (!isa<ObjCMethodDecl>(D)) { 3152 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3153 << Attr.getRange() << Attr.getName() << ExpectedMethod; 3154 return; 3155 } 3156 3157 D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context)); 3158} 3159 3160static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 3161 const AttributeList &Attr) { 3162 3163 QualType returnType; 3164 3165 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 3166 returnType = MD->getResultType(); 3167 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 3168 returnType = PD->getType(); 3169 else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) && 3170 (Attr.getKind() == AttributeList::AT_ns_returns_retained)) 3171 return; // ignore: was handled as a type attribute 3172 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 3173 returnType = FD->getResultType(); 3174 else { 3175 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3176 << Attr.getRange() << Attr.getName() 3177 << ExpectedFunctionOrMethod; 3178 return; 3179 } 3180 3181 bool typeOK; 3182 bool cf; 3183 switch (Attr.getKind()) { 3184 default: llvm_unreachable("invalid ownership attribute"); return; 3185 case AttributeList::AT_ns_returns_autoreleased: 3186 case AttributeList::AT_ns_returns_retained: 3187 case AttributeList::AT_ns_returns_not_retained: 3188 typeOK = isValidSubjectOfNSAttribute(S, returnType); 3189 cf = false; 3190 break; 3191 3192 case AttributeList::AT_cf_returns_retained: 3193 case AttributeList::AT_cf_returns_not_retained: 3194 typeOK = isValidSubjectOfCFAttribute(S, returnType); 3195 cf = true; 3196 break; 3197 } 3198 3199 if (!typeOK) { 3200 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3201 << Attr.getRange() << 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.getRange(), 3211 S.Context)); 3212 return; 3213 case AttributeList::AT_cf_returns_not_retained: 3214 D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(), 3215 S.Context)); 3216 return; 3217 case AttributeList::AT_ns_returns_not_retained: 3218 D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(), 3219 S.Context)); 3220 return; 3221 case AttributeList::AT_cf_returns_retained: 3222 D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(), 3223 S.Context)); 3224 return; 3225 case AttributeList::AT_ns_returns_retained: 3226 D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(), 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(attr.getRange(), S.Context)); 3257} 3258 3259static void handleObjCOwnershipAttr(Sema &S, Decl *D, 3260 const AttributeList &Attr) { 3261 if (hasDeclarator(D)) return; 3262 3263 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3264 << Attr.getRange() << Attr.getName() << 12 /* variable */; 3265} 3266 3267static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 3268 const AttributeList &Attr) { 3269 if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) { 3270 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3271 << Attr.getRange() << Attr.getName() << 12 /* variable */; 3272 return; 3273 } 3274 3275 ValueDecl *vd = cast<ValueDecl>(D); 3276 QualType type = vd->getType(); 3277 3278 if (!type->isDependentType() && 3279 !type->isObjCLifetimeType()) { 3280 S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 3281 << type; 3282 return; 3283 } 3284 3285 Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 3286 3287 // If we have no lifetime yet, check the lifetime we're presumably 3288 // going to infer. 3289 if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 3290 lifetime = type->getObjCARCImplicitLifetime(); 3291 3292 switch (lifetime) { 3293 case Qualifiers::OCL_None: 3294 assert(type->isDependentType() && 3295 "didn't infer lifetime for non-dependent type?"); 3296 break; 3297 3298 case Qualifiers::OCL_Weak: // meaningful 3299 case Qualifiers::OCL_Strong: // meaningful 3300 break; 3301 3302 case Qualifiers::OCL_ExplicitNone: 3303 case Qualifiers::OCL_Autoreleasing: 3304 S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 3305 << (lifetime == Qualifiers::OCL_Autoreleasing); 3306 break; 3307 } 3308 3309 D->addAttr(::new (S.Context) 3310 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context)); 3311} 3312 3313static bool isKnownDeclSpecAttr(const AttributeList &Attr) { 3314 return Attr.getKind() == AttributeList::AT_dllimport || 3315 Attr.getKind() == AttributeList::AT_dllexport || 3316 Attr.getKind() == AttributeList::AT_uuid; 3317} 3318 3319//===----------------------------------------------------------------------===// 3320// Microsoft specific attribute handlers. 3321//===----------------------------------------------------------------------===// 3322 3323static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3324 if (S.LangOpts.Microsoft || S.LangOpts.Borland) { 3325 // check the attribute arguments. 3326 if (!checkAttributeNumArgs(S, Attr, 1)) 3327 return; 3328 3329 Expr *Arg = Attr.getArg(0); 3330 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3331 if (!Str || !Str->isAscii()) { 3332 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3333 << "uuid" << 1; 3334 return; 3335 } 3336 3337 StringRef StrRef = Str->getString(); 3338 3339 bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 3340 StrRef.back() == '}'; 3341 3342 // Validate GUID length. 3343 if (IsCurly && StrRef.size() != 38) { 3344 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3345 return; 3346 } 3347 if (!IsCurly && StrRef.size() != 36) { 3348 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3349 return; 3350 } 3351 3352 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 3353 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 3354 StringRef::iterator I = StrRef.begin(); 3355 if (IsCurly) // Skip the optional '{' 3356 ++I; 3357 3358 for (int i = 0; i < 36; ++i) { 3359 if (i == 8 || i == 13 || i == 18 || i == 23) { 3360 if (*I != '-') { 3361 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3362 return; 3363 } 3364 } else if (!isxdigit(*I)) { 3365 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3366 return; 3367 } 3368 I++; 3369 } 3370 3371 D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, 3372 Str->getString())); 3373 } else 3374 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 3375} 3376 3377//===----------------------------------------------------------------------===// 3378// Top Level Sema Entry Points 3379//===----------------------------------------------------------------------===// 3380 3381static void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 3382 const AttributeList &Attr) { 3383 switch (Attr.getKind()) { 3384 case AttributeList::AT_device: handleDeviceAttr (S, D, Attr); break; 3385 case AttributeList::AT_host: handleHostAttr (S, D, Attr); break; 3386 case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break; 3387 default: 3388 break; 3389 } 3390} 3391 3392static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 3393 const AttributeList &Attr) { 3394 switch (Attr.getKind()) { 3395 case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break; 3396 case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break; 3397 case AttributeList::AT_IBOutletCollection: 3398 handleIBOutletCollection(S, D, Attr); break; 3399 case AttributeList::AT_address_space: 3400 case AttributeList::AT_opencl_image_access: 3401 case AttributeList::AT_objc_gc: 3402 case AttributeList::AT_vector_size: 3403 case AttributeList::AT_neon_vector_type: 3404 case AttributeList::AT_neon_polyvector_type: 3405 // Ignore these, these are type attributes, handled by 3406 // ProcessTypeAttributes. 3407 break; 3408 case AttributeList::AT_device: 3409 case AttributeList::AT_host: 3410 case AttributeList::AT_overloadable: 3411 // Ignore, this is a non-inheritable attribute, handled 3412 // by ProcessNonInheritableDeclAttr. 3413 break; 3414 case AttributeList::AT_alias: handleAliasAttr (S, D, Attr); break; 3415 case AttributeList::AT_aligned: handleAlignedAttr (S, D, Attr); break; 3416 case AttributeList::AT_always_inline: 3417 handleAlwaysInlineAttr (S, D, Attr); break; 3418 case AttributeList::AT_analyzer_noreturn: 3419 handleAnalyzerNoReturnAttr (S, D, Attr); break; 3420 case AttributeList::AT_annotate: handleAnnotateAttr (S, D, Attr); break; 3421 case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break; 3422 case AttributeList::AT_carries_dependency: 3423 handleDependencyAttr (S, D, Attr); break; 3424 case AttributeList::AT_common: handleCommonAttr (S, D, Attr); break; 3425 case AttributeList::AT_constant: handleConstantAttr (S, D, Attr); break; 3426 case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break; 3427 case AttributeList::AT_deprecated: handleDeprecatedAttr (S, D, Attr); break; 3428 case AttributeList::AT_destructor: handleDestructorAttr (S, D, Attr); break; 3429 case AttributeList::AT_ext_vector_type: 3430 handleExtVectorTypeAttr(S, scope, D, Attr); 3431 break; 3432 case AttributeList::AT_format: handleFormatAttr (S, D, Attr); break; 3433 case AttributeList::AT_format_arg: handleFormatArgAttr (S, D, Attr); break; 3434 case AttributeList::AT_global: handleGlobalAttr (S, D, Attr); break; 3435 case AttributeList::AT_gnu_inline: handleGNUInlineAttr (S, D, Attr); break; 3436 case AttributeList::AT_launch_bounds: 3437 handleLaunchBoundsAttr(S, D, Attr); 3438 break; 3439 case AttributeList::AT_mode: handleModeAttr (S, D, Attr); break; 3440 case AttributeList::AT_malloc: handleMallocAttr (S, D, Attr); break; 3441 case AttributeList::AT_may_alias: handleMayAliasAttr (S, D, Attr); break; 3442 case AttributeList::AT_nocommon: handleNoCommonAttr (S, D, Attr); break; 3443 case AttributeList::AT_nonnull: handleNonNullAttr (S, D, Attr); break; 3444 case AttributeList::AT_ownership_returns: 3445 case AttributeList::AT_ownership_takes: 3446 case AttributeList::AT_ownership_holds: 3447 handleOwnershipAttr (S, D, Attr); break; 3448 case AttributeList::AT_naked: handleNakedAttr (S, D, Attr); break; 3449 case AttributeList::AT_noreturn: handleNoReturnAttr (S, D, Attr); break; 3450 case AttributeList::AT_nothrow: handleNothrowAttr (S, D, Attr); break; 3451 case AttributeList::AT_shared: handleSharedAttr (S, D, Attr); break; 3452 case AttributeList::AT_vecreturn: handleVecReturnAttr (S, D, Attr); break; 3453 3454 case AttributeList::AT_objc_ownership: 3455 handleObjCOwnershipAttr(S, D, Attr); break; 3456 case AttributeList::AT_objc_precise_lifetime: 3457 handleObjCPreciseLifetimeAttr(S, D, Attr); break; 3458 3459 case AttributeList::AT_objc_returns_inner_pointer: 3460 handleObjCReturnsInnerPointerAttr(S, D, Attr); break; 3461 3462 // Checker-specific. 3463 case AttributeList::AT_cf_consumed: 3464 case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break; 3465 case AttributeList::AT_ns_consumes_self: 3466 handleNSConsumesSelfAttr(S, D, Attr); break; 3467 3468 case AttributeList::AT_ns_returns_autoreleased: 3469 case AttributeList::AT_ns_returns_not_retained: 3470 case AttributeList::AT_cf_returns_not_retained: 3471 case AttributeList::AT_ns_returns_retained: 3472 case AttributeList::AT_cf_returns_retained: 3473 handleNSReturnsRetainedAttr(S, D, Attr); break; 3474 3475 case AttributeList::AT_reqd_wg_size: 3476 handleReqdWorkGroupSize(S, D, Attr); break; 3477 3478 case AttributeList::AT_init_priority: 3479 handleInitPriorityAttr(S, D, Attr); break; 3480 3481 case AttributeList::AT_packed: handlePackedAttr (S, D, Attr); break; 3482 case AttributeList::AT_MsStruct: handleMsStructAttr (S, D, Attr); break; 3483 case AttributeList::AT_section: handleSectionAttr (S, D, Attr); break; 3484 case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break; 3485 case AttributeList::AT_arc_weakref_unavailable: 3486 handleArcWeakrefUnavailableAttr (S, D, Attr); 3487 break; 3488 case AttributeList::AT_unused: handleUnusedAttr (S, D, Attr); break; 3489 case AttributeList::AT_used: handleUsedAttr (S, D, Attr); break; 3490 case AttributeList::AT_visibility: handleVisibilityAttr (S, D, Attr); break; 3491 case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr); 3492 break; 3493 case AttributeList::AT_weak: handleWeakAttr (S, D, Attr); break; 3494 case AttributeList::AT_weakref: handleWeakRefAttr (S, D, Attr); break; 3495 case AttributeList::AT_weak_import: handleWeakImportAttr (S, D, Attr); break; 3496 case AttributeList::AT_transparent_union: 3497 handleTransparentUnionAttr(S, D, Attr); 3498 break; 3499 case AttributeList::AT_objc_exception: 3500 handleObjCExceptionAttr(S, D, Attr); 3501 break; 3502 case AttributeList::AT_objc_method_family: 3503 handleObjCMethodFamilyAttr(S, D, Attr); 3504 break; 3505 case AttributeList::AT_nsobject: handleObjCNSObject (S, D, Attr); break; 3506 case AttributeList::AT_blocks: handleBlocksAttr (S, D, Attr); break; 3507 case AttributeList::AT_sentinel: handleSentinelAttr (S, D, Attr); break; 3508 case AttributeList::AT_const: handleConstAttr (S, D, Attr); break; 3509 case AttributeList::AT_pure: handlePureAttr (S, D, Attr); break; 3510 case AttributeList::AT_cleanup: handleCleanupAttr (S, D, Attr); break; 3511 case AttributeList::AT_nodebug: handleNoDebugAttr (S, D, Attr); break; 3512 case AttributeList::AT_noinline: handleNoInlineAttr (S, D, Attr); break; 3513 case AttributeList::AT_regparm: handleRegparmAttr (S, D, Attr); break; 3514 case AttributeList::IgnoredAttribute: 3515 // Just ignore 3516 break; 3517 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 3518 handleNoInstrumentFunctionAttr(S, D, Attr); 3519 break; 3520 case AttributeList::AT_stdcall: 3521 case AttributeList::AT_cdecl: 3522 case AttributeList::AT_fastcall: 3523 case AttributeList::AT_thiscall: 3524 case AttributeList::AT_pascal: 3525 case AttributeList::AT_pcs: 3526 handleCallConvAttr(S, D, Attr); 3527 break; 3528 case AttributeList::AT_opencl_kernel_function: 3529 handleOpenCLKernelAttr(S, D, Attr); 3530 break; 3531 case AttributeList::AT_uuid: 3532 handleUuidAttr(S, D, Attr); 3533 break; 3534 3535 // Thread safety attributes: 3536 case AttributeList::AT_guarded_var: 3537 handleGuardedVarAttr(S, D, Attr); 3538 break; 3539 case AttributeList::AT_pt_guarded_var: 3540 handleGuardedVarAttr(S, D, Attr, /*pointer = */true); 3541 break; 3542 case AttributeList::AT_scoped_lockable: 3543 handleLockableAttr(S, D, Attr, /*scoped = */true); 3544 break; 3545 case AttributeList::AT_no_thread_safety_analysis: 3546 handleNoThreadSafetyAttr(S, D, Attr); 3547 break; 3548 case AttributeList::AT_lockable: 3549 handleLockableAttr(S, D, Attr); 3550 break; 3551 case AttributeList::AT_guarded_by: 3552 handleGuardedByAttr(S, D, Attr); 3553 break; 3554 case AttributeList::AT_pt_guarded_by: 3555 handleGuardedByAttr(S, D, Attr, /*pointer = */true); 3556 break; 3557 case AttributeList::AT_exclusive_lock_function: 3558 handleLockFunAttr(S, D, Attr, /*exclusive = */true); 3559 break; 3560 case AttributeList::AT_exclusive_locks_required: 3561 handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true); 3562 break; 3563 case AttributeList::AT_exclusive_trylock_function: 3564 handleTrylockFunAttr(S, D, Attr, /*exclusive = */true); 3565 break; 3566 case AttributeList::AT_lock_returned: 3567 handleLockReturnedAttr(S, D, Attr); 3568 break; 3569 case AttributeList::AT_locks_excluded: 3570 handleLocksExcludedAttr(S, D, Attr); 3571 break; 3572 case AttributeList::AT_shared_lock_function: 3573 handleLockFunAttr(S, D, Attr); 3574 break; 3575 case AttributeList::AT_shared_locks_required: 3576 handleLocksRequiredAttr(S, D, Attr); 3577 break; 3578 case AttributeList::AT_shared_trylock_function: 3579 handleTrylockFunAttr(S, D, Attr); 3580 break; 3581 case AttributeList::AT_unlock_function: 3582 handleUnlockFunAttr(S, D, Attr); 3583 break; 3584 case AttributeList::AT_acquired_before: 3585 handleAcquireOrderAttr(S, D, Attr, /*before = */true); 3586 break; 3587 case AttributeList::AT_acquired_after: 3588 handleAcquireOrderAttr(S, D, Attr, /*before = */false); 3589 break; 3590 3591 default: 3592 // Ask target about the attribute. 3593 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 3594 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 3595 S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 3596 << Attr.getName(); 3597 break; 3598 } 3599} 3600 3601/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 3602/// the attribute applies to decls. If the attribute is a type attribute, just 3603/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 3604/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 3605static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 3606 const AttributeList &Attr, 3607 bool NonInheritable, bool Inheritable) { 3608 if (Attr.isInvalid()) 3609 return; 3610 3611 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 3612 // FIXME: Try to deal with other __declspec attributes! 3613 return; 3614 3615 if (NonInheritable) 3616 ProcessNonInheritableDeclAttr(S, scope, D, Attr); 3617 3618 if (Inheritable) 3619 ProcessInheritableDeclAttr(S, scope, D, Attr); 3620} 3621 3622/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 3623/// attribute list to the specified decl, ignoring any type attributes. 3624void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 3625 const AttributeList *AttrList, 3626 bool NonInheritable, bool Inheritable) { 3627 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 3628 ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable); 3629 } 3630 3631 // GCC accepts 3632 // static int a9 __attribute__((weakref)); 3633 // but that looks really pointless. We reject it. 3634 if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 3635 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 3636 dyn_cast<NamedDecl>(D)->getNameAsString(); 3637 return; 3638 } 3639} 3640 3641/// DeclClonePragmaWeak - clone existing decl (maybe definition), 3642/// #pragma weak needs a non-definition decl and source may not have one 3643NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 3644 SourceLocation Loc) { 3645 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 3646 NamedDecl *NewD = 0; 3647 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 3648 FunctionDecl *NewFD; 3649 // FIXME: Missing call to CheckFunctionDeclaration(). 3650 // FIXME: Mangling? 3651 // FIXME: Is the qualifier info correct? 3652 // FIXME: Is the DeclContext correct? 3653 NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 3654 Loc, Loc, DeclarationName(II), 3655 FD->getType(), FD->getTypeSourceInfo(), 3656 SC_None, SC_None, 3657 false/*isInlineSpecified*/, 3658 FD->hasPrototype(), 3659 false/*isConstexprSpecified*/); 3660 NewD = NewFD; 3661 3662 if (FD->getQualifier()) 3663 NewFD->setQualifierInfo(FD->getQualifierLoc()); 3664 3665 // Fake up parameter variables; they are declared as if this were 3666 // a typedef. 3667 QualType FDTy = FD->getType(); 3668 if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 3669 SmallVector<ParmVarDecl*, 16> Params; 3670 for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), 3671 AE = FT->arg_type_end(); AI != AE; ++AI) { 3672 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI); 3673 Param->setScopeInfo(0, Params.size()); 3674 Params.push_back(Param); 3675 } 3676 NewFD->setParams(Params.data(), Params.size()); 3677 } 3678 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 3679 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 3680 VD->getInnerLocStart(), VD->getLocation(), II, 3681 VD->getType(), VD->getTypeSourceInfo(), 3682 VD->getStorageClass(), 3683 VD->getStorageClassAsWritten()); 3684 if (VD->getQualifier()) { 3685 VarDecl *NewVD = cast<VarDecl>(NewD); 3686 NewVD->setQualifierInfo(VD->getQualifierLoc()); 3687 } 3688 } 3689 return NewD; 3690} 3691 3692/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 3693/// applied to it, possibly with an alias. 3694void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 3695 if (W.getUsed()) return; // only do this once 3696 W.setUsed(true); 3697 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 3698 IdentifierInfo *NDId = ND->getIdentifier(); 3699 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 3700 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 3701 NDId->getName())); 3702 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3703 WeakTopLevelDecl.push_back(NewD); 3704 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 3705 // to insert Decl at TU scope, sorry. 3706 DeclContext *SavedContext = CurContext; 3707 CurContext = Context.getTranslationUnitDecl(); 3708 PushOnScopeChains(NewD, S); 3709 CurContext = SavedContext; 3710 } else { // just add weak to existing 3711 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3712 } 3713} 3714 3715/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 3716/// it, apply them to D. This is a bit tricky because PD can have attributes 3717/// specified in many different places, and we need to find and apply them all. 3718void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 3719 bool NonInheritable, bool Inheritable) { 3720 // It's valid to "forward-declare" #pragma weak, in which case we 3721 // have to do this. 3722 if (Inheritable) { 3723 LoadExternalWeakUndeclaredIdentifiers(); 3724 if (!WeakUndeclaredIdentifiers.empty()) { 3725 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 3726 if (IdentifierInfo *Id = ND->getIdentifier()) { 3727 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 3728 = WeakUndeclaredIdentifiers.find(Id); 3729 if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 3730 WeakInfo W = I->second; 3731 DeclApplyPragmaWeak(S, ND, W); 3732 WeakUndeclaredIdentifiers[Id] = W; 3733 } 3734 } 3735 } 3736 } 3737 } 3738 3739 // Apply decl attributes from the DeclSpec if present. 3740 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 3741 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3742 3743 // Walk the declarator structure, applying decl attributes that were in a type 3744 // position to the decl itself. This handles cases like: 3745 // int *__attr__(x)** D; 3746 // when X is a decl attribute. 3747 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 3748 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 3749 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3750 3751 // Finally, apply any attributes on the decl itself. 3752 if (const AttributeList *Attrs = PD.getAttributes()) 3753 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3754} 3755 3756/// Is the given declaration allowed to use a forbidden type? 3757static bool isForbiddenTypeAllowed(Sema &S, Decl *decl) { 3758 // Private ivars are always okay. Unfortunately, people don't 3759 // always properly make their ivars private, even in system headers. 3760 // Plus we need to make fields okay, too. 3761 if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl)) 3762 return false; 3763 3764 // Require it to be declared in a system header. 3765 return S.Context.getSourceManager().isInSystemHeader(decl->getLocation()); 3766} 3767 3768/// Handle a delayed forbidden-type diagnostic. 3769static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 3770 Decl *decl) { 3771 if (decl && isForbiddenTypeAllowed(S, decl)) { 3772 decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context, 3773 "this system declaration uses an unsupported type")); 3774 return; 3775 } 3776 3777 S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 3778 << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 3779 diag.Triggered = true; 3780} 3781 3782// This duplicates a vector push_back but hides the need to know the 3783// size of the type. 3784void Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) { 3785 assert(StackSize <= StackCapacity); 3786 3787 // Grow the stack if necessary. 3788 if (StackSize == StackCapacity) { 3789 unsigned newCapacity = 2 * StackCapacity + 2; 3790 char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)]; 3791 const char *oldBuffer = (const char*) Stack; 3792 3793 if (StackCapacity) 3794 memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic)); 3795 3796 delete[] oldBuffer; 3797 Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer); 3798 StackCapacity = newCapacity; 3799 } 3800 3801 assert(StackSize < StackCapacity); 3802 new (&Stack[StackSize++]) DelayedDiagnostic(diag); 3803} 3804 3805void Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state, 3806 Decl *decl) { 3807 DelayedDiagnostics &DD = S.DelayedDiagnostics; 3808 3809 // Check the invariants. 3810 assert(DD.StackSize >= state.SavedStackSize); 3811 assert(state.SavedStackSize >= DD.ActiveStackBase); 3812 assert(DD.ParsingDepth > 0); 3813 3814 // Drop the parsing depth. 3815 DD.ParsingDepth--; 3816 3817 // If there are no active diagnostics, we're done. 3818 if (DD.StackSize == DD.ActiveStackBase) 3819 return; 3820 3821 // We only want to actually emit delayed diagnostics when we 3822 // successfully parsed a decl. 3823 if (decl && !decl->isInvalidDecl()) { 3824 // We emit all the active diagnostics, not just those starting 3825 // from the saved state. The idea is this: we get one push for a 3826 // decl spec and another for each declarator; in a decl group like: 3827 // deprecated_typedef foo, *bar, baz(); 3828 // only the declarator pops will be passed decls. This is correct; 3829 // we really do need to consider delayed diagnostics from the decl spec 3830 // for each of the different declarations. 3831 for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) { 3832 DelayedDiagnostic &diag = DD.Stack[i]; 3833 if (diag.Triggered) 3834 continue; 3835 3836 switch (diag.Kind) { 3837 case DelayedDiagnostic::Deprecation: 3838 S.HandleDelayedDeprecationCheck(diag, decl); 3839 break; 3840 3841 case DelayedDiagnostic::Access: 3842 S.HandleDelayedAccessCheck(diag, decl); 3843 break; 3844 3845 case DelayedDiagnostic::ForbiddenType: 3846 handleDelayedForbiddenType(S, diag, decl); 3847 break; 3848 } 3849 } 3850 } 3851 3852 // Destroy all the delayed diagnostics we're about to pop off. 3853 for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i) 3854 DD.Stack[i].Destroy(); 3855 3856 DD.StackSize = state.SavedStackSize; 3857} 3858 3859static bool isDeclDeprecated(Decl *D) { 3860 do { 3861 if (D->isDeprecated()) 3862 return true; 3863 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 3864 return false; 3865} 3866 3867void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 3868 Decl *Ctx) { 3869 if (isDeclDeprecated(Ctx)) 3870 return; 3871 3872 DD.Triggered = true; 3873 if (!DD.getDeprecationMessage().empty()) 3874 Diag(DD.Loc, diag::warn_deprecated_message) 3875 << DD.getDeprecationDecl()->getDeclName() 3876 << DD.getDeprecationMessage(); 3877 else 3878 Diag(DD.Loc, diag::warn_deprecated) 3879 << DD.getDeprecationDecl()->getDeclName(); 3880} 3881 3882void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, 3883 SourceLocation Loc, 3884 const ObjCInterfaceDecl *UnknownObjCClass) { 3885 // Delay if we're currently parsing a declaration. 3886 if (DelayedDiagnostics.shouldDelayDiagnostics()) { 3887 DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message)); 3888 return; 3889 } 3890 3891 // Otherwise, don't warn if our current context is deprecated. 3892 if (isDeclDeprecated(cast<Decl>(CurContext))) 3893 return; 3894 if (!Message.empty()) 3895 Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 3896 << Message; 3897 else { 3898 if (!UnknownObjCClass) 3899 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 3900 else { 3901 Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName(); 3902 Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 3903 } 3904 } 3905} 3906