SemaDeclAttr.cpp revision 19510856727e0e14a3696b2a72c35163bff2a71f
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/Sema.h" 15#include "TargetAttributesSema.h" 16#include "clang/AST/ASTContext.h" 17#include "clang/AST/DeclObjC.h" 18#include "clang/AST/Expr.h" 19#include "clang/Basic/TargetInfo.h" 20#include "clang/Sema/DeclSpec.h" 21#include "llvm/ADT/StringExtras.h" 22using namespace clang; 23 24//===----------------------------------------------------------------------===// 25// Helper functions 26//===----------------------------------------------------------------------===// 27 28static const FunctionType *getFunctionType(const Decl *d, 29 bool blocksToo = true) { 30 QualType Ty; 31 if (const ValueDecl *decl = dyn_cast<ValueDecl>(d)) 32 Ty = decl->getType(); 33 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d)) 34 Ty = decl->getType(); 35 else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 36 Ty = decl->getUnderlyingType(); 37 else 38 return 0; 39 40 if (Ty->isFunctionPointerType()) 41 Ty = Ty->getAs<PointerType>()->getPointeeType(); 42 else if (blocksToo && Ty->isBlockPointerType()) 43 Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 44 45 return Ty->getAs<FunctionType>(); 46} 47 48// FIXME: We should provide an abstraction around a method or function 49// to provide the following bits of information. 50 51/// isFunction - Return true if the given decl has function 52/// type (function or function-typed variable). 53static bool isFunction(const Decl *d) { 54 return getFunctionType(d, false) != NULL; 55} 56 57/// isFunctionOrMethod - Return true if the given decl has function 58/// type (function or function-typed variable) or an Objective-C 59/// method. 60static bool isFunctionOrMethod(const Decl *d) { 61 return isFunction(d)|| isa<ObjCMethodDecl>(d); 62} 63 64/// isFunctionOrMethodOrBlock - Return true if the given decl has function 65/// type (function or function-typed variable) or an Objective-C 66/// method or a block. 67static bool isFunctionOrMethodOrBlock(const Decl *d) { 68 if (isFunctionOrMethod(d)) 69 return true; 70 // check for block is more involved. 71 if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 72 QualType Ty = V->getType(); 73 return Ty->isBlockPointerType(); 74 } 75 return isa<BlockDecl>(d); 76} 77 78/// hasFunctionProto - Return true if the given decl has a argument 79/// information. This decl should have already passed 80/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 81static bool hasFunctionProto(const Decl *d) { 82 if (const FunctionType *FnTy = getFunctionType(d)) 83 return isa<FunctionProtoType>(FnTy); 84 else { 85 assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 86 return true; 87 } 88} 89 90/// getFunctionOrMethodNumArgs - Return number of function or method 91/// arguments. It is an error to call this on a K&R function (use 92/// hasFunctionProto first). 93static unsigned getFunctionOrMethodNumArgs(const Decl *d) { 94 if (const FunctionType *FnTy = getFunctionType(d)) 95 return cast<FunctionProtoType>(FnTy)->getNumArgs(); 96 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 97 return BD->getNumParams(); 98 return cast<ObjCMethodDecl>(d)->param_size(); 99} 100 101static QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) { 102 if (const FunctionType *FnTy = getFunctionType(d)) 103 return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 104 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 105 return BD->getParamDecl(Idx)->getType(); 106 107 return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 108} 109 110static QualType getFunctionOrMethodResultType(const Decl *d) { 111 if (const FunctionType *FnTy = getFunctionType(d)) 112 return cast<FunctionProtoType>(FnTy)->getResultType(); 113 return cast<ObjCMethodDecl>(d)->getResultType(); 114} 115 116static bool isFunctionOrMethodVariadic(const Decl *d) { 117 if (const FunctionType *FnTy = getFunctionType(d)) { 118 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 119 return proto->isVariadic(); 120 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 121 return BD->isVariadic(); 122 else { 123 return cast<ObjCMethodDecl>(d)->isVariadic(); 124 } 125} 126 127static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 128 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 129 if (!PT) 130 return false; 131 132 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 133 if (!Cls) 134 return false; 135 136 IdentifierInfo* ClsName = Cls->getIdentifier(); 137 138 // FIXME: Should we walk the chain of classes? 139 return ClsName == &Ctx.Idents.get("NSString") || 140 ClsName == &Ctx.Idents.get("NSMutableString"); 141} 142 143static inline bool isCFStringType(QualType T, ASTContext &Ctx) { 144 const PointerType *PT = T->getAs<PointerType>(); 145 if (!PT) 146 return false; 147 148 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 149 if (!RT) 150 return false; 151 152 const RecordDecl *RD = RT->getDecl(); 153 if (RD->getTagKind() != TTK_Struct) 154 return false; 155 156 return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 157} 158 159//===----------------------------------------------------------------------===// 160// Attribute Implementations 161//===----------------------------------------------------------------------===// 162 163// FIXME: All this manual attribute parsing code is gross. At the 164// least add some helper functions to check most argument patterns (# 165// and types of args). 166 167static void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 168 const AttributeList &Attr, Sema &S) { 169 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 170 if (tDecl == 0) { 171 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 172 return; 173 } 174 175 QualType curType = tDecl->getUnderlyingType(); 176 177 Expr *sizeExpr; 178 179 // Special case where the argument is a template id. 180 if (Attr.getParameterName()) { 181 CXXScopeSpec SS; 182 UnqualifiedId id; 183 id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 184 sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); 185 } else { 186 // check the attribute arguments. 187 if (Attr.getNumArgs() != 1) { 188 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 189 return; 190 } 191 sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 192 } 193 194 // Instantiate/Install the vector type, and let Sema build the type for us. 195 // This will run the reguired checks. 196 QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc()); 197 if (!T.isNull()) { 198 // FIXME: preserve the old source info. 199 tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 200 201 // Remember this typedef decl, we will need it later for diagnostics. 202 S.ExtVectorDecls.push_back(tDecl); 203 } 204} 205 206static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 207 // check the attribute arguments. 208 if (Attr.getNumArgs() > 0) { 209 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 210 return; 211 } 212 213 if (TagDecl *TD = dyn_cast<TagDecl>(d)) 214 TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 215 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 216 // If the alignment is less than or equal to 8 bits, the packed attribute 217 // has no effect. 218 if (!FD->getType()->isIncompleteType() && 219 S.Context.getTypeAlign(FD->getType()) <= 8) 220 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 221 << Attr.getName() << FD->getType(); 222 else 223 FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 224 } else 225 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 226} 227 228static void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) { 229 // check the attribute arguments. 230 if (Attr.getNumArgs() > 0) { 231 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 232 return; 233 } 234 235 // The IBAction attributes only apply to instance methods. 236 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 237 if (MD->isInstanceMethod()) { 238 d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context)); 239 return; 240 } 241 242 S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName(); 243} 244 245static void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) { 246 // check the attribute arguments. 247 if (Attr.getNumArgs() > 0) { 248 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 249 return; 250 } 251 252 // The IBOutlet attributes only apply to instance variables of 253 // Objective-C classes. 254 if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) { 255 d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context)); 256 return; 257 } 258 259 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 260} 261 262static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr, 263 Sema &S) { 264 265 // The iboutletcollection attribute can have zero or one arguments. 266 if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 267 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 268 return; 269 } 270 271 // The IBOutletCollection attributes only apply to instance variables of 272 // Objective-C classes. 273 if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) { 274 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 275 return; 276 } 277 if (const ValueDecl *VD = dyn_cast<ValueDecl>(d)) 278 if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 279 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 280 << VD->getType() << 0; 281 return; 282 } 283 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d)) 284 if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 285 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 286 << PD->getType() << 1; 287 return; 288 } 289 290 IdentifierInfo *II = Attr.getParameterName(); 291 if (!II) 292 II = &S.Context.Idents.get("id"); 293 294 Sema::TypeTy *TypeRep = S.getTypeName(*II, Attr.getLoc(), 295 S.getScopeForContext(d->getDeclContext()->getParent())); 296 if (!TypeRep) { 297 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 298 return; 299 } 300 QualType QT(QualType::getFromOpaquePtr(TypeRep)); 301 // Diagnose use of non-object type in iboutletcollection attribute. 302 // FIXME. Gnu attribute extension ignores use of builtin types in 303 // attributes. So, __attribute__((iboutletcollection(char))) will be 304 // treated as __attribute__((iboutletcollection())). 305 if (!QT->isObjCIdType() && !QT->isObjCClassType() && 306 !QT->isObjCObjectType()) { 307 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 308 return; 309 } 310 d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context, 311 QT)); 312} 313 314static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 315 // GCC ignores the nonnull attribute on K&R style function prototypes, so we 316 // ignore it as well 317 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 318 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 319 << Attr.getName() << 0 /*function*/; 320 return; 321 } 322 323 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 324 325 // The nonnull attribute only applies to pointers. 326 llvm::SmallVector<unsigned, 10> NonNullArgs; 327 328 for (AttributeList::arg_iterator I=Attr.arg_begin(), 329 E=Attr.arg_end(); I!=E; ++I) { 330 331 332 // The argument must be an integer constant expression. 333 Expr *Ex = static_cast<Expr *>(*I); 334 llvm::APSInt ArgNum(32); 335 if (Ex->isTypeDependent() || Ex->isValueDependent() || 336 !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 337 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 338 << "nonnull" << Ex->getSourceRange(); 339 return; 340 } 341 342 unsigned x = (unsigned) ArgNum.getZExtValue(); 343 344 if (x < 1 || x > NumArgs) { 345 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 346 << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 347 return; 348 } 349 350 --x; 351 352 // Is the function argument a pointer type? 353 QualType T = getFunctionOrMethodArgType(d, x); 354 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 355 // FIXME: Should also highlight argument in decl. 356 S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 357 << "nonnull" << Ex->getSourceRange(); 358 continue; 359 } 360 361 NonNullArgs.push_back(x); 362 } 363 364 // If no arguments were specified to __attribute__((nonnull)) then all pointer 365 // arguments have a nonnull attribute. 366 if (NonNullArgs.empty()) { 367 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 368 QualType T = getFunctionOrMethodArgType(d, I); 369 if (T->isAnyPointerType() || T->isBlockPointerType()) 370 NonNullArgs.push_back(I); 371 } 372 373 if (NonNullArgs.empty()) { 374 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 375 return; 376 } 377 } 378 379 unsigned* start = &NonNullArgs[0]; 380 unsigned size = NonNullArgs.size(); 381 llvm::array_pod_sort(start, start + size); 382 d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start, 383 size)); 384} 385 386static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) { 387 // This attribute must be applied to a function declaration. 388 // The first argument to the attribute must be a string, 389 // the name of the resource, for example "malloc". 390 // The following arguments must be argument indexes, the arguments must be 391 // of integer type for Returns, otherwise of pointer type. 392 // The difference between Holds and Takes is that a pointer may still be used 393 // after being held. free() should be __attribute((ownership_takes)), whereas 394 // a list append function may well be __attribute((ownership_holds)). 395 396 if (!AL.getParameterName()) { 397 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 398 << AL.getName()->getName() << 1; 399 return; 400 } 401 // Figure out our Kind, and check arguments while we're at it. 402 OwnershipAttr::OwnershipKind K; 403 switch (AL.getKind()) { 404 case AttributeList::AT_ownership_takes: 405 K = OwnershipAttr::Takes; 406 if (AL.getNumArgs() < 1) { 407 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 408 return; 409 } 410 break; 411 case AttributeList::AT_ownership_holds: 412 K = OwnershipAttr::Holds; 413 if (AL.getNumArgs() < 1) { 414 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 415 return; 416 } 417 break; 418 case AttributeList::AT_ownership_returns: 419 K = OwnershipAttr::Returns; 420 if (AL.getNumArgs() > 1) { 421 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 422 << AL.getNumArgs() + 1; 423 return; 424 } 425 break; 426 default: 427 // This should never happen given how we are called. 428 llvm_unreachable("Unknown ownership attribute"); 429 } 430 431 if (!isFunction(d) || !hasFunctionProto(d)) { 432 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName() 433 << 0 /*function*/; 434 return; 435 } 436 437 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 438 439 llvm::StringRef Module = AL.getParameterName()->getName(); 440 441 // Normalize the argument, __foo__ becomes foo. 442 if (Module.startswith("__") && Module.endswith("__")) 443 Module = Module.substr(2, Module.size() - 4); 444 445 llvm::SmallVector<unsigned, 10> OwnershipArgs; 446 447 for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 448 ++I) { 449 450 Expr *IdxExpr = static_cast<Expr *>(*I); 451 llvm::APSInt ArgNum(32); 452 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 453 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 454 S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 455 << AL.getName()->getName() << IdxExpr->getSourceRange(); 456 continue; 457 } 458 459 unsigned x = (unsigned) ArgNum.getZExtValue(); 460 461 if (x > NumArgs || x < 1) { 462 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 463 << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 464 continue; 465 } 466 --x; 467 switch (K) { 468 case OwnershipAttr::Takes: 469 case OwnershipAttr::Holds: { 470 // Is the function argument a pointer type? 471 QualType T = getFunctionOrMethodArgType(d, x); 472 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 473 // FIXME: Should also highlight argument in decl. 474 S.Diag(AL.getLoc(), diag::err_ownership_type) 475 << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 476 << "pointer" 477 << IdxExpr->getSourceRange(); 478 continue; 479 } 480 break; 481 } 482 case OwnershipAttr::Returns: { 483 if (AL.getNumArgs() > 1) { 484 // Is the function argument an integer type? 485 Expr *IdxExpr = static_cast<Expr *>(AL.getArg(0)); 486 llvm::APSInt ArgNum(32); 487 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 488 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 489 S.Diag(AL.getLoc(), diag::err_ownership_type) 490 << "ownership_returns" << "integer" 491 << IdxExpr->getSourceRange(); 492 return; 493 } 494 } 495 break; 496 } 497 default: 498 llvm_unreachable("Unknown ownership attribute"); 499 } // switch 500 501 // Check we don't have a conflict with another ownership attribute. 502 for (specific_attr_iterator<OwnershipAttr> 503 i = d->specific_attr_begin<OwnershipAttr>(), 504 e = d->specific_attr_end<OwnershipAttr>(); 505 i != e; ++i) { 506 if ((*i)->getOwnKind() != K) { 507 for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 508 I!=E; ++I) { 509 if (x == *I) { 510 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 511 << AL.getName()->getName() << "ownership_*"; 512 } 513 } 514 } 515 } 516 OwnershipArgs.push_back(x); 517 } 518 519 unsigned* start = OwnershipArgs.data(); 520 unsigned size = OwnershipArgs.size(); 521 llvm::array_pod_sort(start, start + size); 522 523 if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 524 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 525 return; 526 } 527 528 d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 529 start, size)); 530} 531 532static bool isStaticVarOrStaticFunciton(Decl *D) { 533 if (VarDecl *VD = dyn_cast<VarDecl>(D)) 534 return VD->getStorageClass() == VarDecl::Static; 535 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 536 return FD->getStorageClass() == FunctionDecl::Static; 537 return false; 538} 539 540static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) { 541 // Check the attribute arguments. 542 if (Attr.getNumArgs() > 1) { 543 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 544 return; 545 } 546 547 // gcc rejects 548 // class c { 549 // static int a __attribute__((weakref ("v2"))); 550 // static int b() __attribute__((weakref ("f3"))); 551 // }; 552 // and ignores the attributes of 553 // void f(void) { 554 // static int a __attribute__((weakref ("v2"))); 555 // } 556 // we reject them 557 if (const DeclContext *Ctx = d->getDeclContext()) { 558 Ctx = Ctx->getLookupContext(); 559 if (!isa<TranslationUnitDecl>(Ctx) && !isa<NamespaceDecl>(Ctx) ) { 560 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 561 dyn_cast<NamedDecl>(d)->getNameAsString(); 562 return; 563 } 564 } 565 566 // The GCC manual says 567 // 568 // At present, a declaration to which `weakref' is attached can only 569 // be `static'. 570 // 571 // It also says 572 // 573 // Without a TARGET, 574 // given as an argument to `weakref' or to `alias', `weakref' is 575 // equivalent to `weak'. 576 // 577 // gcc 4.4.1 will accept 578 // int a7 __attribute__((weakref)); 579 // as 580 // int a7 __attribute__((weak)); 581 // This looks like a bug in gcc. We reject that for now. We should revisit 582 // it if this behaviour is actually used. 583 584 if (!isStaticVarOrStaticFunciton(d)) { 585 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) << 586 dyn_cast<NamedDecl>(d)->getNameAsString(); 587 return; 588 } 589 590 // GCC rejects 591 // static ((alias ("y"), weakref)). 592 // Should we? How to check that weakref is before or after alias? 593 594 if (Attr.getNumArgs() == 1) { 595 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 596 Arg = Arg->IgnoreParenCasts(); 597 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 598 599 if (Str == 0 || Str->isWide()) { 600 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 601 << "weakref" << 1; 602 return; 603 } 604 // GCC will accept anything as the argument of weakref. Should we 605 // check for an existing decl? 606 d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString())); 607 } 608 609 d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context)); 610} 611 612static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 613 // check the attribute arguments. 614 if (Attr.getNumArgs() != 1) { 615 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 616 return; 617 } 618 619 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 620 Arg = Arg->IgnoreParenCasts(); 621 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 622 623 if (Str == 0 || Str->isWide()) { 624 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 625 << "alias" << 1; 626 return; 627 } 628 629 // FIXME: check if target symbol exists in current file 630 631 d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString())); 632} 633 634static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 635 Sema &S) { 636 // check the attribute arguments. 637 if (Attr.getNumArgs() != 0) { 638 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 639 return; 640 } 641 642 if (!isa<FunctionDecl>(d)) { 643 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 644 << Attr.getName() << 0 /*function*/; 645 return; 646 } 647 648 d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context)); 649} 650 651static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 652 // check the attribute arguments. 653 if (Attr.getNumArgs() != 0) { 654 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 655 return; 656 } 657 658 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 659 QualType RetTy = FD->getResultType(); 660 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 661 d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context)); 662 return; 663 } 664 } 665 666 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 667} 668 669static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 670 /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */ 671 assert(Attr.isInvalid() == false); 672 d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context)); 673} 674 675static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 676 Sema &S) { 677 678 // The checking path for 'noreturn' and 'analyzer_noreturn' are different 679 // because 'analyzer_noreturn' does not impact the type. 680 681 if (Attr.getNumArgs() != 0) { 682 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 683 return; 684 } 685 686 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 687 ValueDecl *VD = dyn_cast<ValueDecl>(d); 688 if (VD == 0 || (!VD->getType()->isBlockPointerType() 689 && !VD->getType()->isFunctionPointerType())) { 690 S.Diag(Attr.getLoc(), 691 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 692 : diag::warn_attribute_wrong_decl_type) 693 << Attr.getName() << 0 /*function*/; 694 return; 695 } 696 } 697 698 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context)); 699} 700 701// PS3 PPU-specific. 702static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr, 703 Sema &S) { 704/* 705 Returning a Vector Class in Registers 706 707 According to the PPU ABI specifications, a class with a single member of vector type is returned in 708 memory when used as the return value of a function. This results in inefficient code when implementing 709 vector classes. To return the value in a single vector register, add the vecreturn attribute to the class 710 definition. This attribute is also applicable to struct types. 711 712 Example: 713 714 struct Vector 715 { 716 __vector float xyzw; 717 } __attribute__((vecreturn)); 718 719 Vector Add(Vector lhs, Vector rhs) 720 { 721 Vector result; 722 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 723 return result; // This will be returned in a register 724 } 725*/ 726 if (!isa<CXXRecordDecl>(d)) { 727 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 728 << Attr.getName() << 9 /*class*/; 729 return; 730 } 731 732 if (d->getAttr<VecReturnAttr>()) { 733 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 734 return; 735 } 736 737 d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context)); 738} 739 740static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 741 if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 742 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 743 << Attr.getName() << 8 /*function, method, or parameter*/; 744 return; 745 } 746 // FIXME: Actually store the attribute on the declaration 747} 748 749static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 750 // check the attribute arguments. 751 if (Attr.getNumArgs() != 0) { 752 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 753 return; 754 } 755 756 if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) && 757 !isa<TypeDecl>(d)) { 758 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 759 << Attr.getName() << 2 /*variable and function*/; 760 return; 761 } 762 763 d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context)); 764} 765 766static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 767 // check the attribute arguments. 768 if (Attr.getNumArgs() != 0) { 769 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 770 return; 771 } 772 773 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 774 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 775 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 776 return; 777 } 778 } else if (!isFunctionOrMethod(d)) { 779 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 780 << Attr.getName() << 2 /*variable and function*/; 781 return; 782 } 783 784 d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 785} 786 787static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 788 // check the attribute arguments. 789 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 790 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 791 << "0 or 1"; 792 return; 793 } 794 795 int priority = 65535; // FIXME: Do not hardcode such constants. 796 if (Attr.getNumArgs() > 0) { 797 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 798 llvm::APSInt Idx(32); 799 if (E->isTypeDependent() || E->isValueDependent() || 800 !E->isIntegerConstantExpr(Idx, S.Context)) { 801 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 802 << "constructor" << 1 << E->getSourceRange(); 803 return; 804 } 805 priority = Idx.getZExtValue(); 806 } 807 808 if (!isa<FunctionDecl>(d)) { 809 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 810 << Attr.getName() << 0 /*function*/; 811 return; 812 } 813 814 d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, priority)); 815} 816 817static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 818 // check the attribute arguments. 819 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 820 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 821 << "0 or 1"; 822 return; 823 } 824 825 int priority = 65535; // FIXME: Do not hardcode such constants. 826 if (Attr.getNumArgs() > 0) { 827 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 828 llvm::APSInt Idx(32); 829 if (E->isTypeDependent() || E->isValueDependent() || 830 !E->isIntegerConstantExpr(Idx, S.Context)) { 831 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 832 << "destructor" << 1 << E->getSourceRange(); 833 return; 834 } 835 priority = Idx.getZExtValue(); 836 } 837 838 if (!isa<FunctionDecl>(d)) { 839 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 840 << Attr.getName() << 0 /*function*/; 841 return; 842 } 843 844 d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, priority)); 845} 846 847static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 848 // check the attribute arguments. 849 if (Attr.getNumArgs() != 0) { 850 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 851 return; 852 } 853 854 d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context)); 855} 856 857static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 858 // check the attribute arguments. 859 if (Attr.getNumArgs() != 0) { 860 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 861 return; 862 } 863 864 d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context)); 865} 866 867static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 868 // check the attribute arguments. 869 if (Attr.getNumArgs() != 1) { 870 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 871 return; 872 } 873 874 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 875 Arg = Arg->IgnoreParenCasts(); 876 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 877 878 if (Str == 0 || Str->isWide()) { 879 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 880 << "visibility" << 1; 881 return; 882 } 883 884 llvm::StringRef TypeStr = Str->getString(); 885 VisibilityAttr::VisibilityType type; 886 887 if (TypeStr == "default") 888 type = VisibilityAttr::Default; 889 else if (TypeStr == "hidden") 890 type = VisibilityAttr::Hidden; 891 else if (TypeStr == "internal") 892 type = VisibilityAttr::Hidden; // FIXME 893 else if (TypeStr == "protected") 894 type = VisibilityAttr::Protected; 895 else { 896 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 897 return; 898 } 899 900 d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type)); 901} 902 903static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 904 Sema &S) { 905 if (Attr.getNumArgs() != 0) { 906 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 907 return; 908 } 909 910 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 911 if (OCI == 0) { 912 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 913 return; 914 } 915 916 D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context)); 917} 918 919static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 920 if (Attr.getNumArgs() != 0) { 921 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 922 return; 923 } 924 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 925 QualType T = TD->getUnderlyingType(); 926 if (!T->isPointerType() || 927 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 928 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 929 return; 930 } 931 } 932 D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context)); 933} 934 935static void 936HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 937 if (Attr.getNumArgs() != 0) { 938 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 939 return; 940 } 941 942 if (!isa<FunctionDecl>(D)) { 943 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 944 return; 945 } 946 947 D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context)); 948} 949 950static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 951 if (!Attr.getParameterName()) { 952 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 953 << "blocks" << 1; 954 return; 955 } 956 957 if (Attr.getNumArgs() != 0) { 958 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 959 return; 960 } 961 962 BlocksAttr::BlockType type; 963 if (Attr.getParameterName()->isStr("byref")) 964 type = BlocksAttr::ByRef; 965 else { 966 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 967 << "blocks" << Attr.getParameterName(); 968 return; 969 } 970 971 d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type)); 972} 973 974static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 975 // check the attribute arguments. 976 if (Attr.getNumArgs() > 2) { 977 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 978 << "0, 1 or 2"; 979 return; 980 } 981 982 int sentinel = 0; 983 if (Attr.getNumArgs() > 0) { 984 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 985 llvm::APSInt Idx(32); 986 if (E->isTypeDependent() || E->isValueDependent() || 987 !E->isIntegerConstantExpr(Idx, S.Context)) { 988 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 989 << "sentinel" << 1 << E->getSourceRange(); 990 return; 991 } 992 sentinel = Idx.getZExtValue(); 993 994 if (sentinel < 0) { 995 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 996 << E->getSourceRange(); 997 return; 998 } 999 } 1000 1001 int nullPos = 0; 1002 if (Attr.getNumArgs() > 1) { 1003 Expr *E = static_cast<Expr *>(Attr.getArg(1)); 1004 llvm::APSInt Idx(32); 1005 if (E->isTypeDependent() || E->isValueDependent() || 1006 !E->isIntegerConstantExpr(Idx, S.Context)) { 1007 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1008 << "sentinel" << 2 << E->getSourceRange(); 1009 return; 1010 } 1011 nullPos = Idx.getZExtValue(); 1012 1013 if (nullPos > 1 || nullPos < 0) { 1014 // FIXME: This error message could be improved, it would be nice 1015 // to say what the bounds actually are. 1016 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1017 << E->getSourceRange(); 1018 return; 1019 } 1020 } 1021 1022 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 1023 const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 1024 assert(FT && "FunctionDecl has non-function type?"); 1025 1026 if (isa<FunctionNoProtoType>(FT)) { 1027 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1028 return; 1029 } 1030 1031 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 1032 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1033 return; 1034 } 1035 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 1036 if (!MD->isVariadic()) { 1037 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1038 return; 1039 } 1040 } else if (isa<BlockDecl>(d)) { 1041 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 1042 // caller. 1043 ; 1044 } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 1045 QualType Ty = V->getType(); 1046 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 1047 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 1048 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 1049 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 1050 int m = Ty->isFunctionPointerType() ? 0 : 1; 1051 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 1052 return; 1053 } 1054 } else { 1055 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1056 << Attr.getName() << 6 /*function, method or block */; 1057 return; 1058 } 1059 } else { 1060 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1061 << Attr.getName() << 6 /*function, method or block */; 1062 return; 1063 } 1064 d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, nullPos)); 1065} 1066 1067static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 1068 // check the attribute arguments. 1069 if (Attr.getNumArgs() != 0) { 1070 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1071 return; 1072 } 1073 1074 if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1075 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1076 << Attr.getName() << 0 /*function*/; 1077 return; 1078 } 1079 1080 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1081 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1082 << Attr.getName() << 0; 1083 return; 1084 } 1085 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1086 if (MD->getResultType()->isVoidType()) { 1087 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1088 << Attr.getName() << 1; 1089 return; 1090 } 1091 1092 D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context)); 1093} 1094 1095static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1096 // check the attribute arguments. 1097 if (Attr.getNumArgs() != 0) { 1098 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1099 return; 1100 } 1101 1102 /* weak only applies to non-static declarations */ 1103 if (isStaticVarOrStaticFunciton(D)) { 1104 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 1105 dyn_cast<NamedDecl>(D)->getNameAsString(); 1106 return; 1107 } 1108 1109 // TODO: could also be applied to methods? 1110 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 1111 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1112 << Attr.getName() << 2 /*variable and function*/; 1113 return; 1114 } 1115 1116 D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context)); 1117} 1118 1119static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1120 // check the attribute arguments. 1121 if (Attr.getNumArgs() != 0) { 1122 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1123 return; 1124 } 1125 1126 // weak_import only applies to variable & function declarations. 1127 bool isDef = false; 1128 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 1129 isDef = (!VD->hasExternalStorage() || VD->getInit()); 1130 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1131 isDef = FD->hasBody(); 1132 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 1133 // We ignore weak import on properties and methods 1134 return; 1135 } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) { 1136 // Don't issue the warning for darwin as target; yet, ignore the attribute. 1137 if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin || 1138 !isa<ObjCInterfaceDecl>(D)) 1139 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1140 << Attr.getName() << 2 /*variable and function*/; 1141 return; 1142 } 1143 1144 // Merge should handle any subsequent violations. 1145 if (isDef) { 1146 S.Diag(Attr.getLoc(), 1147 diag::warn_attribute_weak_import_invalid_on_definition) 1148 << "weak_import" << 2 /*variable and function*/; 1149 return; 1150 } 1151 1152 D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context)); 1153} 1154 1155static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 1156 Sema &S) { 1157 // Attribute has 3 arguments. 1158 if (Attr.getNumArgs() != 3) { 1159 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1160 return; 1161 } 1162 1163 unsigned WGSize[3]; 1164 for (unsigned i = 0; i < 3; ++i) { 1165 Expr *E = static_cast<Expr *>(Attr.getArg(i)); 1166 llvm::APSInt ArgNum(32); 1167 if (E->isTypeDependent() || E->isValueDependent() || 1168 !E->isIntegerConstantExpr(ArgNum, S.Context)) { 1169 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1170 << "reqd_work_group_size" << E->getSourceRange(); 1171 return; 1172 } 1173 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 1174 } 1175 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context, 1176 WGSize[0], WGSize[1], 1177 WGSize[2])); 1178} 1179 1180static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1181 // Attribute has no arguments. 1182 if (Attr.getNumArgs() != 1) { 1183 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1184 return; 1185 } 1186 1187 // Make sure that there is a string literal as the sections's single 1188 // argument. 1189 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1190 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1191 if (!SE) { 1192 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 1193 return; 1194 } 1195 1196 // If the target wants to validate the section specifier, make it happen. 1197 std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 1198 if (!Error.empty()) { 1199 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1200 << Error; 1201 return; 1202 } 1203 1204 // This attribute cannot be applied to local variables. 1205 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 1206 S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 1207 return; 1208 } 1209 1210 D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, SE->getString())); 1211} 1212 1213 1214static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1215 // check the attribute arguments. 1216 if (Attr.getNumArgs() != 0) { 1217 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1218 return; 1219 } 1220 1221 d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context)); 1222} 1223 1224static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1225 // check the attribute arguments. 1226 if (Attr.getNumArgs() != 0) { 1227 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1228 return; 1229 } 1230 1231 d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context)); 1232} 1233 1234static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1235 // check the attribute arguments. 1236 if (Attr.getNumArgs() != 0) { 1237 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1238 return; 1239 } 1240 1241 d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context)); 1242} 1243 1244static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1245 if (!Attr.getParameterName()) { 1246 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1247 return; 1248 } 1249 1250 if (Attr.getNumArgs() != 0) { 1251 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1252 return; 1253 } 1254 1255 VarDecl *VD = dyn_cast<VarDecl>(d); 1256 1257 if (!VD || !VD->hasLocalStorage()) { 1258 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1259 return; 1260 } 1261 1262 // Look up the function 1263 // FIXME: Lookup probably isn't looking in the right place 1264 // FIXME: The lookup source location should be in the attribute, not the 1265 // start of the attribute. 1266 NamedDecl *CleanupDecl 1267 = S.LookupSingleName(S.TUScope, Attr.getParameterName(), Attr.getLoc(), 1268 Sema::LookupOrdinaryName); 1269 if (!CleanupDecl) { 1270 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1271 Attr.getParameterName(); 1272 return; 1273 } 1274 1275 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1276 if (!FD) { 1277 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1278 Attr.getParameterName(); 1279 return; 1280 } 1281 1282 if (FD->getNumParams() != 1) { 1283 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1284 Attr.getParameterName(); 1285 return; 1286 } 1287 1288 // We're currently more strict than GCC about what function types we accept. 1289 // If this ever proves to be a problem it should be easy to fix. 1290 QualType Ty = S.Context.getPointerType(VD->getType()); 1291 QualType ParamTy = FD->getParamDecl(0)->getType(); 1292 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1293 S.Diag(Attr.getLoc(), 1294 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1295 Attr.getParameterName() << ParamTy << Ty; 1296 return; 1297 } 1298 1299 d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD)); 1300} 1301 1302/// Handle __attribute__((format_arg((idx)))) attribute based on 1303/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1304static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1305 if (Attr.getNumArgs() != 1) { 1306 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1307 return; 1308 } 1309 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1310 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1311 << Attr.getName() << 0 /*function*/; 1312 return; 1313 } 1314 // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1315 // needed in order to be compatible with GCC the index must start with 1. 1316 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1317 unsigned FirstIdx = 1; 1318 // checks for the 2nd argument 1319 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1320 llvm::APSInt Idx(32); 1321 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1322 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1323 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1324 << "format" << 2 << IdxExpr->getSourceRange(); 1325 return; 1326 } 1327 1328 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1329 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1330 << "format" << 2 << IdxExpr->getSourceRange(); 1331 return; 1332 } 1333 1334 unsigned ArgIdx = Idx.getZExtValue() - 1; 1335 1336 // make sure the format string is really a string 1337 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1338 1339 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 1340 if (not_nsstring_type && 1341 !isCFStringType(Ty, S.Context) && 1342 (!Ty->isPointerType() || 1343 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1344 // FIXME: Should highlight the actual expression that has the wrong type. 1345 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1346 << (not_nsstring_type ? "a string type" : "an NSString") 1347 << IdxExpr->getSourceRange(); 1348 return; 1349 } 1350 Ty = getFunctionOrMethodResultType(d); 1351 if (!isNSStringType(Ty, S.Context) && 1352 !isCFStringType(Ty, S.Context) && 1353 (!Ty->isPointerType() || 1354 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1355 // FIXME: Should highlight the actual expression that has the wrong type. 1356 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1357 << (not_nsstring_type ? "string type" : "NSString") 1358 << IdxExpr->getSourceRange(); 1359 return; 1360 } 1361 1362 d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, Idx.getZExtValue())); 1363} 1364 1365enum FormatAttrKind { 1366 CFStringFormat, 1367 NSStringFormat, 1368 StrftimeFormat, 1369 SupportedFormat, 1370 IgnoredFormat, 1371 InvalidFormat 1372}; 1373 1374/// getFormatAttrKind - Map from format attribute names to supported format 1375/// types. 1376static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 1377 // Check for formats that get handled specially. 1378 if (Format == "NSString") 1379 return NSStringFormat; 1380 if (Format == "CFString") 1381 return CFStringFormat; 1382 if (Format == "strftime") 1383 return StrftimeFormat; 1384 1385 // Otherwise, check for supported formats. 1386 if (Format == "scanf" || Format == "printf" || Format == "printf0" || 1387 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 1388 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 1389 Format == "zcmn_err") 1390 return SupportedFormat; 1391 1392 if (Format == "gcc_diag" || Format == "gcc_cdiag" || 1393 Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 1394 return IgnoredFormat; 1395 1396 return InvalidFormat; 1397} 1398 1399/// Handle __attribute__((init_priority(priority))) attributes based on 1400/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 1401static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 1402 Sema &S) { 1403 if (!S.getLangOptions().CPlusPlus) { 1404 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1405 return; 1406 } 1407 1408 if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) { 1409 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1410 Attr.setInvalid(); 1411 return; 1412 } 1413 QualType T = dyn_cast<VarDecl>(d)->getType(); 1414 if (S.Context.getAsArrayType(T)) 1415 T = S.Context.getBaseElementType(T); 1416 if (!T->getAs<RecordType>()) { 1417 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1418 Attr.setInvalid(); 1419 return; 1420 } 1421 1422 if (Attr.getNumArgs() != 1) { 1423 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1424 Attr.setInvalid(); 1425 return; 1426 } 1427 Expr *priorityExpr = static_cast<Expr *>(Attr.getArg(0)); 1428 1429 llvm::APSInt priority(32); 1430 if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 1431 !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 1432 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1433 << "init_priority" << priorityExpr->getSourceRange(); 1434 Attr.setInvalid(); 1435 return; 1436 } 1437 unsigned prioritynum = priority.getZExtValue(); 1438 if (prioritynum < 101 || prioritynum > 65535) { 1439 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 1440 << priorityExpr->getSourceRange(); 1441 Attr.setInvalid(); 1442 return; 1443 } 1444 d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, prioritynum)); 1445} 1446 1447/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1448/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1449static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1450 1451 if (!Attr.getParameterName()) { 1452 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1453 << "format" << 1; 1454 return; 1455 } 1456 1457 if (Attr.getNumArgs() != 2) { 1458 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1459 return; 1460 } 1461 1462 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1463 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1464 << Attr.getName() << 0 /*function*/; 1465 return; 1466 } 1467 1468 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1469 unsigned FirstIdx = 1; 1470 1471 llvm::StringRef Format = Attr.getParameterName()->getName(); 1472 1473 // Normalize the argument, __foo__ becomes foo. 1474 if (Format.startswith("__") && Format.endswith("__")) 1475 Format = Format.substr(2, Format.size() - 4); 1476 1477 // Check for supported formats. 1478 FormatAttrKind Kind = getFormatAttrKind(Format); 1479 1480 if (Kind == IgnoredFormat) 1481 return; 1482 1483 if (Kind == InvalidFormat) { 1484 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1485 << "format" << Attr.getParameterName()->getName(); 1486 return; 1487 } 1488 1489 // checks for the 2nd argument 1490 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1491 llvm::APSInt Idx(32); 1492 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1493 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1494 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1495 << "format" << 2 << IdxExpr->getSourceRange(); 1496 return; 1497 } 1498 1499 // FIXME: We should handle the implicit 'this' parameter in a more generic 1500 // way that can be used for other arguments. 1501 bool HasImplicitThisParam = false; 1502 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 1503 if (MD->isInstance()) { 1504 HasImplicitThisParam = true; 1505 NumArgs++; 1506 } 1507 } 1508 1509 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1510 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1511 << "format" << 2 << IdxExpr->getSourceRange(); 1512 return; 1513 } 1514 1515 // FIXME: Do we need to bounds check? 1516 unsigned ArgIdx = Idx.getZExtValue() - 1; 1517 1518 if (HasImplicitThisParam) { 1519 if (ArgIdx == 0) { 1520 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1521 << "a string type" << IdxExpr->getSourceRange(); 1522 return; 1523 } 1524 ArgIdx--; 1525 } 1526 1527 // make sure the format string is really a string 1528 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1529 1530 if (Kind == CFStringFormat) { 1531 if (!isCFStringType(Ty, S.Context)) { 1532 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1533 << "a CFString" << IdxExpr->getSourceRange(); 1534 return; 1535 } 1536 } else if (Kind == NSStringFormat) { 1537 // FIXME: do we need to check if the type is NSString*? What are the 1538 // semantics? 1539 if (!isNSStringType(Ty, S.Context)) { 1540 // FIXME: Should highlight the actual expression that has the wrong type. 1541 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1542 << "an NSString" << IdxExpr->getSourceRange(); 1543 return; 1544 } 1545 } else if (!Ty->isPointerType() || 1546 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1547 // FIXME: Should highlight the actual expression that has the wrong type. 1548 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1549 << "a string type" << IdxExpr->getSourceRange(); 1550 return; 1551 } 1552 1553 // check the 3rd argument 1554 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1555 llvm::APSInt FirstArg(32); 1556 if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 1557 !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1558 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1559 << "format" << 3 << FirstArgExpr->getSourceRange(); 1560 return; 1561 } 1562 1563 // check if the function is variadic if the 3rd argument non-zero 1564 if (FirstArg != 0) { 1565 if (isFunctionOrMethodVariadic(d)) { 1566 ++NumArgs; // +1 for ... 1567 } else { 1568 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1569 return; 1570 } 1571 } 1572 1573 // strftime requires FirstArg to be 0 because it doesn't read from any 1574 // variable the input is just the current time + the format string. 1575 if (Kind == StrftimeFormat) { 1576 if (FirstArg != 0) { 1577 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1578 << FirstArgExpr->getSourceRange(); 1579 return; 1580 } 1581 // if 0 it disables parameter checking (to use with e.g. va_list) 1582 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1583 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1584 << "format" << 3 << FirstArgExpr->getSourceRange(); 1585 return; 1586 } 1587 1588 d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format, 1589 Idx.getZExtValue(), 1590 FirstArg.getZExtValue())); 1591} 1592 1593static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1594 Sema &S) { 1595 // check the attribute arguments. 1596 if (Attr.getNumArgs() != 0) { 1597 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1598 return; 1599 } 1600 1601 // Try to find the underlying union declaration. 1602 RecordDecl *RD = 0; 1603 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1604 if (TD && TD->getUnderlyingType()->isUnionType()) 1605 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1606 else 1607 RD = dyn_cast<RecordDecl>(d); 1608 1609 if (!RD || !RD->isUnion()) { 1610 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1611 << Attr.getName() << 1 /*union*/; 1612 return; 1613 } 1614 1615 if (!RD->isDefinition()) { 1616 S.Diag(Attr.getLoc(), 1617 diag::warn_transparent_union_attribute_not_definition); 1618 return; 1619 } 1620 1621 RecordDecl::field_iterator Field = RD->field_begin(), 1622 FieldEnd = RD->field_end(); 1623 if (Field == FieldEnd) { 1624 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1625 return; 1626 } 1627 1628 FieldDecl *FirstField = *Field; 1629 QualType FirstType = FirstField->getType(); 1630 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 1631 S.Diag(FirstField->getLocation(), 1632 diag::warn_transparent_union_attribute_floating) 1633 << FirstType->isVectorType() << FirstType; 1634 return; 1635 } 1636 1637 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1638 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1639 for (; Field != FieldEnd; ++Field) { 1640 QualType FieldType = Field->getType(); 1641 if (S.Context.getTypeSize(FieldType) != FirstSize || 1642 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1643 // Warn if we drop the attribute. 1644 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1645 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1646 : S.Context.getTypeAlign(FieldType); 1647 S.Diag(Field->getLocation(), 1648 diag::warn_transparent_union_attribute_field_size_align) 1649 << isSize << Field->getDeclName() << FieldBits; 1650 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1651 S.Diag(FirstField->getLocation(), 1652 diag::note_transparent_union_first_field_size_align) 1653 << isSize << FirstBits; 1654 return; 1655 } 1656 } 1657 1658 RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context)); 1659} 1660 1661static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1662 // check the attribute arguments. 1663 if (Attr.getNumArgs() != 1) { 1664 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1665 return; 1666 } 1667 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1668 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1669 1670 // Make sure that there is a string literal as the annotation's single 1671 // argument. 1672 if (!SE) { 1673 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 1674 return; 1675 } 1676 d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString())); 1677} 1678 1679static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1680 // check the attribute arguments. 1681 if (Attr.getNumArgs() > 1) { 1682 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1683 return; 1684 } 1685 1686 //FIXME: The C++0x version of this attribute has more limited applicabilty 1687 // than GNU's, and should error out when it is used to specify a 1688 // weaker alignment, rather than being silently ignored. 1689 1690 if (Attr.getNumArgs() == 0) { 1691 D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0)); 1692 return; 1693 } 1694 1695 S.AddAlignedAttr(Attr.getLoc(), D, static_cast<Expr *>(Attr.getArg(0))); 1696} 1697 1698void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { 1699 if (E->isTypeDependent() || E->isValueDependent()) { 1700 // Save dependent expressions in the AST to be instantiated. 1701 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 1702 return; 1703 } 1704 1705 // FIXME: Cache the number on the Attr object? 1706 llvm::APSInt Alignment(32); 1707 if (!E->isIntegerConstantExpr(Alignment, Context)) { 1708 Diag(AttrLoc, diag::err_attribute_argument_not_int) 1709 << "aligned" << E->getSourceRange(); 1710 return; 1711 } 1712 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1713 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 1714 << E->getSourceRange(); 1715 return; 1716 } 1717 1718 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 1719} 1720 1721void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) { 1722 // FIXME: Cache the number on the Attr object if non-dependent? 1723 // FIXME: Perform checking of type validity 1724 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS)); 1725 return; 1726} 1727 1728/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1729/// type. 1730/// 1731/// Despite what would be logical, the mode attribute is a decl attribute, not a 1732/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1733/// HImode, not an intermediate pointer. 1734static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1735 // This attribute isn't documented, but glibc uses it. It changes 1736 // the width of an int or unsigned int to the specified size. 1737 1738 // Check that there aren't any arguments 1739 if (Attr.getNumArgs() != 0) { 1740 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1741 return; 1742 } 1743 1744 IdentifierInfo *Name = Attr.getParameterName(); 1745 if (!Name) { 1746 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1747 return; 1748 } 1749 1750 llvm::StringRef Str = Attr.getParameterName()->getName(); 1751 1752 // Normalize the attribute name, __foo__ becomes foo. 1753 if (Str.startswith("__") && Str.endswith("__")) 1754 Str = Str.substr(2, Str.size() - 4); 1755 1756 unsigned DestWidth = 0; 1757 bool IntegerMode = true; 1758 bool ComplexMode = false; 1759 switch (Str.size()) { 1760 case 2: 1761 switch (Str[0]) { 1762 case 'Q': DestWidth = 8; break; 1763 case 'H': DestWidth = 16; break; 1764 case 'S': DestWidth = 32; break; 1765 case 'D': DestWidth = 64; break; 1766 case 'X': DestWidth = 96; break; 1767 case 'T': DestWidth = 128; break; 1768 } 1769 if (Str[1] == 'F') { 1770 IntegerMode = false; 1771 } else if (Str[1] == 'C') { 1772 IntegerMode = false; 1773 ComplexMode = true; 1774 } else if (Str[1] != 'I') { 1775 DestWidth = 0; 1776 } 1777 break; 1778 case 4: 1779 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1780 // pointer on PIC16 and other embedded platforms. 1781 if (Str == "word") 1782 DestWidth = S.Context.Target.getPointerWidth(0); 1783 else if (Str == "byte") 1784 DestWidth = S.Context.Target.getCharWidth(); 1785 break; 1786 case 7: 1787 if (Str == "pointer") 1788 DestWidth = S.Context.Target.getPointerWidth(0); 1789 break; 1790 } 1791 1792 QualType OldTy; 1793 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1794 OldTy = TD->getUnderlyingType(); 1795 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1796 OldTy = VD->getType(); 1797 else { 1798 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1799 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1800 return; 1801 } 1802 1803 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 1804 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1805 else if (IntegerMode) { 1806 if (!OldTy->isIntegralOrEnumerationType()) 1807 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1808 } else if (ComplexMode) { 1809 if (!OldTy->isComplexType()) 1810 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1811 } else { 1812 if (!OldTy->isFloatingType()) 1813 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1814 } 1815 1816 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1817 // and friends, at least with glibc. 1818 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1819 // width on unusual platforms. 1820 // FIXME: Make sure floating-point mappings are accurate 1821 // FIXME: Support XF and TF types 1822 QualType NewTy; 1823 switch (DestWidth) { 1824 case 0: 1825 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1826 return; 1827 default: 1828 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1829 return; 1830 case 8: 1831 if (!IntegerMode) { 1832 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1833 return; 1834 } 1835 if (OldTy->isSignedIntegerType()) 1836 NewTy = S.Context.SignedCharTy; 1837 else 1838 NewTy = S.Context.UnsignedCharTy; 1839 break; 1840 case 16: 1841 if (!IntegerMode) { 1842 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1843 return; 1844 } 1845 if (OldTy->isSignedIntegerType()) 1846 NewTy = S.Context.ShortTy; 1847 else 1848 NewTy = S.Context.UnsignedShortTy; 1849 break; 1850 case 32: 1851 if (!IntegerMode) 1852 NewTy = S.Context.FloatTy; 1853 else if (OldTy->isSignedIntegerType()) 1854 NewTy = S.Context.IntTy; 1855 else 1856 NewTy = S.Context.UnsignedIntTy; 1857 break; 1858 case 64: 1859 if (!IntegerMode) 1860 NewTy = S.Context.DoubleTy; 1861 else if (OldTy->isSignedIntegerType()) 1862 if (S.Context.Target.getLongWidth() == 64) 1863 NewTy = S.Context.LongTy; 1864 else 1865 NewTy = S.Context.LongLongTy; 1866 else 1867 if (S.Context.Target.getLongWidth() == 64) 1868 NewTy = S.Context.UnsignedLongTy; 1869 else 1870 NewTy = S.Context.UnsignedLongLongTy; 1871 break; 1872 case 96: 1873 NewTy = S.Context.LongDoubleTy; 1874 break; 1875 case 128: 1876 if (!IntegerMode) { 1877 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1878 return; 1879 } 1880 if (OldTy->isSignedIntegerType()) 1881 NewTy = S.Context.Int128Ty; 1882 else 1883 NewTy = S.Context.UnsignedInt128Ty; 1884 break; 1885 } 1886 1887 if (ComplexMode) { 1888 NewTy = S.Context.getComplexType(NewTy); 1889 } 1890 1891 // Install the new type. 1892 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1893 // FIXME: preserve existing source info. 1894 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 1895 } else 1896 cast<ValueDecl>(D)->setType(NewTy); 1897} 1898 1899static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1900 // check the attribute arguments. 1901 if (Attr.getNumArgs() > 0) { 1902 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1903 return; 1904 } 1905 1906 if (!isFunctionOrMethod(d)) { 1907 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1908 << Attr.getName() << 0 /*function*/; 1909 return; 1910 } 1911 1912 d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context)); 1913} 1914 1915static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1916 // check the attribute arguments. 1917 if (Attr.getNumArgs() != 0) { 1918 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1919 return; 1920 } 1921 1922 if (!isa<FunctionDecl>(d)) { 1923 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1924 << Attr.getName() << 0 /*function*/; 1925 return; 1926 } 1927 1928 d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context)); 1929} 1930 1931static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr, 1932 Sema &S) { 1933 // check the attribute arguments. 1934 if (Attr.getNumArgs() != 0) { 1935 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1936 return; 1937 } 1938 1939 if (!isa<FunctionDecl>(d)) { 1940 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1941 << Attr.getName() << 0 /*function*/; 1942 return; 1943 } 1944 1945 d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), S.Context)); 1946} 1947 1948static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1949 // check the attribute arguments. 1950 if (Attr.getNumArgs() != 0) { 1951 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1952 return; 1953 } 1954 1955 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1956 if (Fn == 0) { 1957 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1958 << Attr.getName() << 0 /*function*/; 1959 return; 1960 } 1961 1962 if (!Fn->isInlineSpecified()) { 1963 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1964 return; 1965 } 1966 1967 d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context)); 1968} 1969 1970static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1971 // Diagnostic is emitted elsewhere: here we store the (valid) Attr 1972 // in the Decl node for syntactic reasoning, e.g., pretty-printing. 1973 assert(Attr.isInvalid() == false); 1974 1975 switch (Attr.getKind()) { 1976 case AttributeList::AT_fastcall: 1977 d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context)); 1978 return; 1979 case AttributeList::AT_stdcall: 1980 d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context)); 1981 return; 1982 case AttributeList::AT_thiscall: 1983 d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context)); 1984 case AttributeList::AT_cdecl: 1985 d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context)); 1986 return; 1987 default: 1988 llvm_unreachable("unexpected attribute kind"); 1989 return; 1990 } 1991} 1992 1993static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1994 // check the attribute arguments. 1995 if (Attr.getNumArgs() != 1) { 1996 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1997 return; 1998 } 1999 2000 if (!isFunctionOrMethod(d)) { 2001 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2002 << Attr.getName() << 0 /*function*/; 2003 return; 2004 } 2005 2006 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 2007 llvm::APSInt NumParams(32); 2008 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 2009 !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 2010 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 2011 << "regparm" << NumParamsExpr->getSourceRange(); 2012 return; 2013 } 2014 2015 if (S.Context.Target.getRegParmMax() == 0) { 2016 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 2017 << NumParamsExpr->getSourceRange(); 2018 return; 2019 } 2020 2021 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 2022 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 2023 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 2024 return; 2025 } 2026 2027 d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, 2028 NumParams.getZExtValue())); 2029} 2030 2031static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2032 // check the attribute arguments. 2033 if (Attr.getNumArgs() != 0) { 2034 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2035 return; 2036 } 2037 2038 if (!isa<CXXRecordDecl>(d) 2039 && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 2040 S.Diag(Attr.getLoc(), 2041 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2042 : diag::warn_attribute_wrong_decl_type) 2043 << Attr.getName() << 7 /*virtual method or class*/; 2044 return; 2045 } 2046 2047 // FIXME: Conform to C++0x redeclaration rules. 2048 2049 if (d->getAttr<FinalAttr>()) { 2050 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 2051 return; 2052 } 2053 2054 d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context)); 2055} 2056 2057//===----------------------------------------------------------------------===// 2058// C++0x member checking attributes 2059//===----------------------------------------------------------------------===// 2060 2061static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2062 if (Attr.getNumArgs() != 0) { 2063 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2064 return; 2065 } 2066 2067 if (!isa<CXXRecordDecl>(d)) { 2068 S.Diag(Attr.getLoc(), 2069 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2070 : diag::warn_attribute_wrong_decl_type) 2071 << Attr.getName() << 9 /*class*/; 2072 return; 2073 } 2074 2075 if (d->getAttr<BaseCheckAttr>()) { 2076 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 2077 return; 2078 } 2079 2080 d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context)); 2081} 2082 2083static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2084 if (Attr.getNumArgs() != 0) { 2085 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2086 return; 2087 } 2088 2089 if (!isa<RecordDecl>(d->getDeclContext())) { 2090 // FIXME: It's not the type that's the problem 2091 S.Diag(Attr.getLoc(), 2092 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2093 : diag::warn_attribute_wrong_decl_type) 2094 << Attr.getName() << 11 /*member*/; 2095 return; 2096 } 2097 2098 // FIXME: Conform to C++0x redeclaration rules. 2099 2100 if (d->getAttr<HidingAttr>()) { 2101 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 2102 return; 2103 } 2104 2105 d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context)); 2106} 2107 2108static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2109 if (Attr.getNumArgs() != 0) { 2110 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2111 return; 2112 } 2113 2114 if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 2115 // FIXME: It's not the type that's the problem 2116 S.Diag(Attr.getLoc(), 2117 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2118 : diag::warn_attribute_wrong_decl_type) 2119 << Attr.getName() << 10 /*virtual method*/; 2120 return; 2121 } 2122 2123 // FIXME: Conform to C++0x redeclaration rules. 2124 2125 if (d->getAttr<OverrideAttr>()) { 2126 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 2127 return; 2128 } 2129 2130 d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context)); 2131} 2132 2133//===----------------------------------------------------------------------===// 2134// Checker-specific attribute handlers. 2135//===----------------------------------------------------------------------===// 2136 2137static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 2138 Sema &S) { 2139 2140 QualType RetTy; 2141 2142 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 2143 RetTy = MD->getResultType(); 2144 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 2145 RetTy = FD->getResultType(); 2146 else { 2147 SourceLocation L = Attr.getLoc(); 2148 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 2149 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 2150 return; 2151 } 2152 2153 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 2154 || RetTy->getAs<ObjCObjectPointerType>())) { 2155 SourceLocation L = Attr.getLoc(); 2156 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 2157 << SourceRange(L, L) << Attr.getName(); 2158 return; 2159 } 2160 2161 switch (Attr.getKind()) { 2162 default: 2163 assert(0 && "invalid ownership attribute"); 2164 return; 2165 case AttributeList::AT_cf_returns_not_retained: 2166 d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), S.Context)); 2167 return; 2168 case AttributeList::AT_ns_returns_not_retained: 2169 d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), S.Context)); 2170 return; 2171 case AttributeList::AT_cf_returns_retained: 2172 d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), S.Context)); 2173 return; 2174 case AttributeList::AT_ns_returns_retained: 2175 d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), S.Context)); 2176 return; 2177 }; 2178} 2179 2180static bool isKnownDeclSpecAttr(const AttributeList &Attr) { 2181 return Attr.getKind() == AttributeList::AT_dllimport || 2182 Attr.getKind() == AttributeList::AT_dllexport; 2183} 2184 2185//===----------------------------------------------------------------------===// 2186// Top Level Sema Entry Points 2187//===----------------------------------------------------------------------===// 2188 2189/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 2190/// the attribute applies to decls. If the attribute is a type attribute, just 2191/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 2192/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 2193static void ProcessDeclAttribute(Scope *scope, Decl *D, 2194 const AttributeList &Attr, Sema &S) { 2195 if (Attr.isInvalid()) 2196 return; 2197 2198 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 2199 // FIXME: Try to deal with other __declspec attributes! 2200 return; 2201 switch (Attr.getKind()) { 2202 case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 2203 case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 2204 case AttributeList::AT_IBOutletCollection: 2205 HandleIBOutletCollection(D, Attr, S); break; 2206 case AttributeList::AT_address_space: 2207 case AttributeList::AT_objc_gc: 2208 case AttributeList::AT_vector_size: 2209 // Ignore these, these are type attributes, handled by 2210 // ProcessTypeAttributes. 2211 break; 2212 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 2213 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 2214 case AttributeList::AT_always_inline: 2215 HandleAlwaysInlineAttr (D, Attr, S); break; 2216 case AttributeList::AT_analyzer_noreturn: 2217 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 2218 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 2219 case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 2220 case AttributeList::AT_carries_dependency: 2221 HandleDependencyAttr (D, Attr, S); break; 2222 case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 2223 case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 2224 case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 2225 case AttributeList::AT_ext_vector_type: 2226 HandleExtVectorTypeAttr(scope, D, Attr, S); 2227 break; 2228 case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 2229 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 2230 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 2231 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 2232 case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 2233 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 2234 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 2235 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 2236 case AttributeList::AT_ownership_returns: 2237 case AttributeList::AT_ownership_takes: 2238 case AttributeList::AT_ownership_holds: 2239 HandleOwnershipAttr (D, Attr, S); break; 2240 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 2241 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 2242 case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 2243 case AttributeList::AT_vecreturn: HandleVecReturnAttr (D, Attr, S); break; 2244 2245 // Checker-specific. 2246 case AttributeList::AT_ns_returns_not_retained: 2247 case AttributeList::AT_cf_returns_not_retained: 2248 case AttributeList::AT_ns_returns_retained: 2249 case AttributeList::AT_cf_returns_retained: 2250 HandleNSReturnsRetainedAttr(D, Attr, S); break; 2251 2252 case AttributeList::AT_reqd_wg_size: 2253 HandleReqdWorkGroupSize(D, Attr, S); break; 2254 2255 case AttributeList::AT_init_priority: 2256 HandleInitPriorityAttr(D, Attr, S); break; 2257 2258 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 2259 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 2260 case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 2261 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 2262 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 2263 case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 2264 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 2265 break; 2266 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 2267 case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 2268 case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 2269 case AttributeList::AT_transparent_union: 2270 HandleTransparentUnionAttr(D, Attr, S); 2271 break; 2272 case AttributeList::AT_objc_exception: 2273 HandleObjCExceptionAttr(D, Attr, S); 2274 break; 2275 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 2276 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 2277 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 2278 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 2279 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 2280 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 2281 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 2282 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 2283 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 2284 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 2285 case AttributeList::IgnoredAttribute: 2286 // Just ignore 2287 break; 2288 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 2289 HandleNoInstrumentFunctionAttr(D, Attr, S); 2290 break; 2291 case AttributeList::AT_stdcall: 2292 case AttributeList::AT_cdecl: 2293 case AttributeList::AT_fastcall: 2294 case AttributeList::AT_thiscall: 2295 HandleCallConvAttr(D, Attr, S); 2296 break; 2297 default: 2298 // Ask target about the attribute. 2299 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 2300 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 2301 S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 2302 << Attr.getName(); 2303 break; 2304 } 2305} 2306 2307/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 2308/// attribute list to the specified decl, ignoring any type attributes. 2309void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 2310 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 2311 ProcessDeclAttribute(S, D, *l, *this); 2312 } 2313 2314 // GCC accepts 2315 // static int a9 __attribute__((weakref)); 2316 // but that looks really pointless. We reject it. 2317 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 2318 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 2319 dyn_cast<NamedDecl>(D)->getNameAsString(); 2320 return; 2321 } 2322} 2323 2324/// DeclClonePragmaWeak - clone existing decl (maybe definition), 2325/// #pragma weak needs a non-definition decl and source may not have one 2326NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 2327 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 2328 NamedDecl *NewD = 0; 2329 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 2330 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 2331 FD->getLocation(), DeclarationName(II), 2332 FD->getType(), FD->getTypeSourceInfo()); 2333 if (FD->getQualifier()) { 2334 FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 2335 NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 2336 } 2337 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 2338 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 2339 VD->getLocation(), II, 2340 VD->getType(), VD->getTypeSourceInfo(), 2341 VD->getStorageClass(), 2342 VD->getStorageClassAsWritten()); 2343 if (VD->getQualifier()) { 2344 VarDecl *NewVD = cast<VarDecl>(NewD); 2345 NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 2346 } 2347 } 2348 return NewD; 2349} 2350 2351/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 2352/// applied to it, possibly with an alias. 2353void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 2354 if (W.getUsed()) return; // only do this once 2355 W.setUsed(true); 2356 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 2357 IdentifierInfo *NDId = ND->getIdentifier(); 2358 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 2359 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 2360 NDId->getName())); 2361 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2362 WeakTopLevelDecl.push_back(NewD); 2363 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 2364 // to insert Decl at TU scope, sorry. 2365 DeclContext *SavedContext = CurContext; 2366 CurContext = Context.getTranslationUnitDecl(); 2367 PushOnScopeChains(NewD, S); 2368 CurContext = SavedContext; 2369 } else { // just add weak to existing 2370 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2371 } 2372} 2373 2374/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 2375/// it, apply them to D. This is a bit tricky because PD can have attributes 2376/// specified in many different places, and we need to find and apply them all. 2377void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 2378 // Handle #pragma weak 2379 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 2380 if (ND->hasLinkage()) { 2381 WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 2382 if (W != WeakInfo()) { 2383 // Identifier referenced by #pragma weak before it was declared 2384 DeclApplyPragmaWeak(S, ND, W); 2385 WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 2386 } 2387 } 2388 } 2389 2390 // Apply decl attributes from the DeclSpec if present. 2391 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 2392 ProcessDeclAttributeList(S, D, Attrs); 2393 2394 // Walk the declarator structure, applying decl attributes that were in a type 2395 // position to the decl itself. This handles cases like: 2396 // int *__attr__(x)** D; 2397 // when X is a decl attribute. 2398 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 2399 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 2400 ProcessDeclAttributeList(S, D, Attrs); 2401 2402 // Finally, apply any attributes on the decl itself. 2403 if (const AttributeList *Attrs = PD.getAttributes()) 2404 ProcessDeclAttributeList(S, D, Attrs); 2405} 2406 2407/// PushParsingDeclaration - Enter a new "scope" of deprecation 2408/// warnings. 2409/// 2410/// The state token we use is the start index of this scope 2411/// on the warning stack. 2412Action::ParsingDeclStackState Sema::PushParsingDeclaration() { 2413 ParsingDeclDepth++; 2414 return (ParsingDeclStackState) DelayedDiagnostics.size(); 2415} 2416 2417void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) { 2418 assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 2419 ParsingDeclDepth--; 2420 2421 if (DelayedDiagnostics.empty()) 2422 return; 2423 2424 unsigned SavedIndex = (unsigned) S; 2425 assert(SavedIndex <= DelayedDiagnostics.size() && 2426 "saved index is out of bounds"); 2427 2428 unsigned E = DelayedDiagnostics.size(); 2429 2430 // We only want to actually emit delayed diagnostics when we 2431 // successfully parsed a decl. 2432 Decl *D = Ctx ? Ctx.getAs<Decl>() : 0; 2433 if (D) { 2434 // We really do want to start with 0 here. We get one push for a 2435 // decl spec and another for each declarator; in a decl group like: 2436 // deprecated_typedef foo, *bar, baz(); 2437 // only the declarator pops will be passed decls. This is correct; 2438 // we really do need to consider delayed diagnostics from the decl spec 2439 // for each of the different declarations. 2440 for (unsigned I = 0; I != E; ++I) { 2441 if (DelayedDiagnostics[I].Triggered) 2442 continue; 2443 2444 switch (DelayedDiagnostics[I].Kind) { 2445 case DelayedDiagnostic::Deprecation: 2446 HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 2447 break; 2448 2449 case DelayedDiagnostic::Access: 2450 HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 2451 break; 2452 } 2453 } 2454 } 2455 2456 // Destroy all the delayed diagnostics we're about to pop off. 2457 for (unsigned I = SavedIndex; I != E; ++I) 2458 DelayedDiagnostics[I].destroy(); 2459 2460 DelayedDiagnostics.set_size(SavedIndex); 2461} 2462 2463static bool isDeclDeprecated(Decl *D) { 2464 do { 2465 if (D->hasAttr<DeprecatedAttr>()) 2466 return true; 2467 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 2468 return false; 2469} 2470 2471void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD, 2472 Decl *Ctx) { 2473 if (isDeclDeprecated(Ctx)) 2474 return; 2475 2476 DD.Triggered = true; 2477 Diag(DD.Loc, diag::warn_deprecated) 2478 << DD.DeprecationData.Decl->getDeclName(); 2479} 2480 2481void Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) { 2482 // Delay if we're currently parsing a declaration. 2483 if (ParsingDeclDepth) { 2484 DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D)); 2485 return; 2486 } 2487 2488 // Otherwise, don't warn if our current context is deprecated. 2489 if (isDeclDeprecated(cast<Decl>(CurContext))) 2490 return; 2491 2492 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 2493} 2494