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