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