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