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