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