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