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