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