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