SemaDeclAttr.cpp revision c8a316e75b46cbfaa7303b3b0e749e666ea4b3a9
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/Parse/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 bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 670 Sema &S) { 671 // check the attribute arguments. 672 if (Attr.getNumArgs() != 0) { 673 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 674 return false; 675 } 676 677 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 678 ValueDecl *VD = dyn_cast<ValueDecl>(d); 679 if (VD == 0 || (!VD->getType()->isBlockPointerType() 680 && !VD->getType()->isFunctionPointerType())) { 681 S.Diag(Attr.getLoc(), 682 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 683 : diag::warn_attribute_wrong_decl_type) 684 << Attr.getName() << 0 /*function*/; 685 return false; 686 } 687 } 688 689 return true; 690} 691 692static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 693 /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */ 694 assert(Attr.isInvalid() == false); 695 d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context)); 696} 697 698static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 699 Sema &S) { 700 if (HandleCommonNoReturnAttr(d, Attr, S)) 701 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context)); 702} 703 704// PS3 PPU-specific. 705static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr, 706 Sema &S) { 707/* 708 Returning a Vector Class in Registers 709 710 According to the PPU ABI specifications, a class with a single member of vector type is returned in 711 memory when used as the return value of a function. This results in inefficient code when implementing 712 vector classes. To return the value in a single vector register, add the vecreturn attribute to the class 713 definition. This attribute is also applicable to struct types. 714 715 Example: 716 717 struct Vector 718 { 719 __vector float xyzw; 720 } __attribute__((vecreturn)); 721 722 Vector Add(Vector lhs, Vector rhs) 723 { 724 Vector result; 725 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 726 return result; // This will be returned in a register 727 } 728*/ 729 if (!isa<CXXRecordDecl>(d)) { 730 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 731 << Attr.getName() << 9 /*class*/; 732 return; 733 } 734 735 if (d->getAttr<VecReturnAttr>()) { 736 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 737 return; 738 } 739 740 d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context)); 741} 742 743static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 744 if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 745 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 746 << Attr.getName() << 8 /*function, method, or parameter*/; 747 return; 748 } 749 // FIXME: Actually store the attribute on the declaration 750} 751 752static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 753 // check the attribute arguments. 754 if (Attr.getNumArgs() != 0) { 755 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 756 return; 757 } 758 759 if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) && 760 !isa<TypeDecl>(d)) { 761 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 762 << Attr.getName() << 2 /*variable and function*/; 763 return; 764 } 765 766 d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context)); 767} 768 769static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 770 // check the attribute arguments. 771 if (Attr.getNumArgs() != 0) { 772 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 773 return; 774 } 775 776 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 777 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 778 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 779 return; 780 } 781 } else if (!isFunctionOrMethod(d)) { 782 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 783 << Attr.getName() << 2 /*variable and function*/; 784 return; 785 } 786 787 d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 788} 789 790static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 791 // check the attribute arguments. 792 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 793 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 794 << "0 or 1"; 795 return; 796 } 797 798 int priority = 65535; // FIXME: Do not hardcode such constants. 799 if (Attr.getNumArgs() > 0) { 800 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 801 llvm::APSInt Idx(32); 802 if (E->isTypeDependent() || E->isValueDependent() || 803 !E->isIntegerConstantExpr(Idx, S.Context)) { 804 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 805 << "constructor" << 1 << E->getSourceRange(); 806 return; 807 } 808 priority = Idx.getZExtValue(); 809 } 810 811 if (!isa<FunctionDecl>(d)) { 812 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 813 << Attr.getName() << 0 /*function*/; 814 return; 815 } 816 817 d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, priority)); 818} 819 820static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 821 // check the attribute arguments. 822 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 823 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 824 << "0 or 1"; 825 return; 826 } 827 828 int priority = 65535; // FIXME: Do not hardcode such constants. 829 if (Attr.getNumArgs() > 0) { 830 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 831 llvm::APSInt Idx(32); 832 if (E->isTypeDependent() || E->isValueDependent() || 833 !E->isIntegerConstantExpr(Idx, S.Context)) { 834 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 835 << "destructor" << 1 << E->getSourceRange(); 836 return; 837 } 838 priority = Idx.getZExtValue(); 839 } 840 841 if (!isa<FunctionDecl>(d)) { 842 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 843 << Attr.getName() << 0 /*function*/; 844 return; 845 } 846 847 d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, priority)); 848} 849 850static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 851 // check the attribute arguments. 852 if (Attr.getNumArgs() != 0) { 853 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 854 return; 855 } 856 857 d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context)); 858} 859 860static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 861 // check the attribute arguments. 862 if (Attr.getNumArgs() != 0) { 863 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 864 return; 865 } 866 867 d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context)); 868} 869 870static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 871 // check the attribute arguments. 872 if (Attr.getNumArgs() != 1) { 873 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 874 return; 875 } 876 877 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 878 Arg = Arg->IgnoreParenCasts(); 879 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 880 881 if (Str == 0 || Str->isWide()) { 882 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 883 << "visibility" << 1; 884 return; 885 } 886 887 llvm::StringRef TypeStr = Str->getString(); 888 VisibilityAttr::VisibilityType type; 889 890 if (TypeStr == "default") 891 type = VisibilityAttr::Default; 892 else if (TypeStr == "hidden") 893 type = VisibilityAttr::Hidden; 894 else if (TypeStr == "internal") 895 type = VisibilityAttr::Hidden; // FIXME 896 else if (TypeStr == "protected") 897 type = VisibilityAttr::Protected; 898 else { 899 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 900 return; 901 } 902 903 d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type)); 904} 905 906static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 907 Sema &S) { 908 if (Attr.getNumArgs() != 0) { 909 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 910 return; 911 } 912 913 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 914 if (OCI == 0) { 915 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 916 return; 917 } 918 919 D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context)); 920} 921 922static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 923 if (Attr.getNumArgs() != 0) { 924 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 925 return; 926 } 927 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 928 QualType T = TD->getUnderlyingType(); 929 if (!T->isPointerType() || 930 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 931 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 932 return; 933 } 934 } 935 D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context)); 936} 937 938static void 939HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 940 if (Attr.getNumArgs() != 0) { 941 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 942 return; 943 } 944 945 if (!isa<FunctionDecl>(D)) { 946 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 947 return; 948 } 949 950 D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context)); 951} 952 953static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 954 if (!Attr.getParameterName()) { 955 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 956 << "blocks" << 1; 957 return; 958 } 959 960 if (Attr.getNumArgs() != 0) { 961 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 962 return; 963 } 964 965 BlocksAttr::BlockType type; 966 if (Attr.getParameterName()->isStr("byref")) 967 type = BlocksAttr::ByRef; 968 else { 969 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 970 << "blocks" << Attr.getParameterName(); 971 return; 972 } 973 974 d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type)); 975} 976 977static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 978 // check the attribute arguments. 979 if (Attr.getNumArgs() > 2) { 980 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 981 << "0, 1 or 2"; 982 return; 983 } 984 985 int sentinel = 0; 986 if (Attr.getNumArgs() > 0) { 987 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 988 llvm::APSInt Idx(32); 989 if (E->isTypeDependent() || E->isValueDependent() || 990 !E->isIntegerConstantExpr(Idx, S.Context)) { 991 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 992 << "sentinel" << 1 << E->getSourceRange(); 993 return; 994 } 995 sentinel = Idx.getZExtValue(); 996 997 if (sentinel < 0) { 998 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 999 << E->getSourceRange(); 1000 return; 1001 } 1002 } 1003 1004 int nullPos = 0; 1005 if (Attr.getNumArgs() > 1) { 1006 Expr *E = static_cast<Expr *>(Attr.getArg(1)); 1007 llvm::APSInt Idx(32); 1008 if (E->isTypeDependent() || E->isValueDependent() || 1009 !E->isIntegerConstantExpr(Idx, S.Context)) { 1010 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1011 << "sentinel" << 2 << E->getSourceRange(); 1012 return; 1013 } 1014 nullPos = Idx.getZExtValue(); 1015 1016 if (nullPos > 1 || nullPos < 0) { 1017 // FIXME: This error message could be improved, it would be nice 1018 // to say what the bounds actually are. 1019 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1020 << E->getSourceRange(); 1021 return; 1022 } 1023 } 1024 1025 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 1026 const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 1027 assert(FT && "FunctionDecl has non-function type?"); 1028 1029 if (isa<FunctionNoProtoType>(FT)) { 1030 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1031 return; 1032 } 1033 1034 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 1035 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1036 return; 1037 } 1038 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 1039 if (!MD->isVariadic()) { 1040 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1041 return; 1042 } 1043 } else if (isa<BlockDecl>(d)) { 1044 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 1045 // caller. 1046 ; 1047 } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 1048 QualType Ty = V->getType(); 1049 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 1050 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 1051 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 1052 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 1053 int m = Ty->isFunctionPointerType() ? 0 : 1; 1054 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 1055 return; 1056 } 1057 } else { 1058 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1059 << Attr.getName() << 6 /*function, method or block */; 1060 return; 1061 } 1062 } else { 1063 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1064 << Attr.getName() << 6 /*function, method or block */; 1065 return; 1066 } 1067 d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, nullPos)); 1068} 1069 1070static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 1071 // check the attribute arguments. 1072 if (Attr.getNumArgs() != 0) { 1073 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1074 return; 1075 } 1076 1077 if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1078 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1079 << Attr.getName() << 0 /*function*/; 1080 return; 1081 } 1082 1083 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1084 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1085 << Attr.getName() << 0; 1086 return; 1087 } 1088 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1089 if (MD->getResultType()->isVoidType()) { 1090 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1091 << Attr.getName() << 1; 1092 return; 1093 } 1094 1095 D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context)); 1096} 1097 1098static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1099 // check the attribute arguments. 1100 if (Attr.getNumArgs() != 0) { 1101 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1102 return; 1103 } 1104 1105 /* weak only applies to non-static declarations */ 1106 if (isStaticVarOrStaticFunciton(D)) { 1107 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 1108 dyn_cast<NamedDecl>(D)->getNameAsString(); 1109 return; 1110 } 1111 1112 // TODO: could also be applied to methods? 1113 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 1114 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1115 << Attr.getName() << 2 /*variable and function*/; 1116 return; 1117 } 1118 1119 D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context)); 1120} 1121 1122static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1123 // check the attribute arguments. 1124 if (Attr.getNumArgs() != 0) { 1125 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1126 return; 1127 } 1128 1129 // weak_import only applies to variable & function declarations. 1130 bool isDef = false; 1131 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 1132 isDef = (!VD->hasExternalStorage() || VD->getInit()); 1133 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1134 isDef = FD->hasBody(); 1135 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 1136 // We ignore weak import on properties and methods 1137 return; 1138 } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) { 1139 // Don't issue the warning for darwin as target; yet, ignore the attribute. 1140 if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin || 1141 !isa<ObjCInterfaceDecl>(D)) 1142 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1143 << Attr.getName() << 2 /*variable and function*/; 1144 return; 1145 } 1146 1147 // Merge should handle any subsequent violations. 1148 if (isDef) { 1149 S.Diag(Attr.getLoc(), 1150 diag::warn_attribute_weak_import_invalid_on_definition) 1151 << "weak_import" << 2 /*variable and function*/; 1152 return; 1153 } 1154 1155 D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context)); 1156} 1157 1158static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 1159 Sema &S) { 1160 // Attribute has 3 arguments. 1161 if (Attr.getNumArgs() != 3) { 1162 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1163 return; 1164 } 1165 1166 unsigned WGSize[3]; 1167 for (unsigned i = 0; i < 3; ++i) { 1168 Expr *E = static_cast<Expr *>(Attr.getArg(i)); 1169 llvm::APSInt ArgNum(32); 1170 if (E->isTypeDependent() || E->isValueDependent() || 1171 !E->isIntegerConstantExpr(ArgNum, S.Context)) { 1172 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1173 << "reqd_work_group_size" << E->getSourceRange(); 1174 return; 1175 } 1176 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 1177 } 1178 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context, 1179 WGSize[0], WGSize[1], 1180 WGSize[2])); 1181} 1182 1183static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1184 // Attribute has no arguments. 1185 if (Attr.getNumArgs() != 1) { 1186 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1187 return; 1188 } 1189 1190 // Make sure that there is a string literal as the sections's single 1191 // argument. 1192 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1193 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1194 if (!SE) { 1195 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 1196 return; 1197 } 1198 1199 // If the target wants to validate the section specifier, make it happen. 1200 std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 1201 if (!Error.empty()) { 1202 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1203 << Error; 1204 return; 1205 } 1206 1207 // This attribute cannot be applied to local variables. 1208 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 1209 S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 1210 return; 1211 } 1212 1213 D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, SE->getString())); 1214} 1215 1216 1217static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1218 // check the attribute arguments. 1219 if (Attr.getNumArgs() != 0) { 1220 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1221 return; 1222 } 1223 1224 d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context)); 1225} 1226 1227static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1228 // check the attribute arguments. 1229 if (Attr.getNumArgs() != 0) { 1230 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1231 return; 1232 } 1233 1234 d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context)); 1235} 1236 1237static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1238 // check the attribute arguments. 1239 if (Attr.getNumArgs() != 0) { 1240 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1241 return; 1242 } 1243 1244 d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context)); 1245} 1246 1247static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1248 if (!Attr.getParameterName()) { 1249 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1250 return; 1251 } 1252 1253 if (Attr.getNumArgs() != 0) { 1254 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1255 return; 1256 } 1257 1258 VarDecl *VD = dyn_cast<VarDecl>(d); 1259 1260 if (!VD || !VD->hasLocalStorage()) { 1261 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1262 return; 1263 } 1264 1265 // Look up the function 1266 // FIXME: Lookup probably isn't looking in the right place 1267 // FIXME: The lookup source location should be in the attribute, not the 1268 // start of the attribute. 1269 NamedDecl *CleanupDecl 1270 = S.LookupSingleName(S.TUScope, Attr.getParameterName(), Attr.getLoc(), 1271 Sema::LookupOrdinaryName); 1272 if (!CleanupDecl) { 1273 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1274 Attr.getParameterName(); 1275 return; 1276 } 1277 1278 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1279 if (!FD) { 1280 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1281 Attr.getParameterName(); 1282 return; 1283 } 1284 1285 if (FD->getNumParams() != 1) { 1286 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1287 Attr.getParameterName(); 1288 return; 1289 } 1290 1291 // We're currently more strict than GCC about what function types we accept. 1292 // If this ever proves to be a problem it should be easy to fix. 1293 QualType Ty = S.Context.getPointerType(VD->getType()); 1294 QualType ParamTy = FD->getParamDecl(0)->getType(); 1295 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1296 S.Diag(Attr.getLoc(), 1297 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1298 Attr.getParameterName() << ParamTy << Ty; 1299 return; 1300 } 1301 1302 d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD)); 1303} 1304 1305/// Handle __attribute__((format_arg((idx)))) attribute based on 1306/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1307static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1308 if (Attr.getNumArgs() != 1) { 1309 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1310 return; 1311 } 1312 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1313 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1314 << Attr.getName() << 0 /*function*/; 1315 return; 1316 } 1317 // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1318 // needed in order to be compatible with GCC the index must start with 1. 1319 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1320 unsigned FirstIdx = 1; 1321 // checks for the 2nd argument 1322 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1323 llvm::APSInt Idx(32); 1324 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1325 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1326 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1327 << "format" << 2 << IdxExpr->getSourceRange(); 1328 return; 1329 } 1330 1331 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1332 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1333 << "format" << 2 << IdxExpr->getSourceRange(); 1334 return; 1335 } 1336 1337 unsigned ArgIdx = Idx.getZExtValue() - 1; 1338 1339 // make sure the format string is really a string 1340 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1341 1342 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 1343 if (not_nsstring_type && 1344 !isCFStringType(Ty, S.Context) && 1345 (!Ty->isPointerType() || 1346 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1347 // FIXME: Should highlight the actual expression that has the wrong type. 1348 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1349 << (not_nsstring_type ? "a string type" : "an NSString") 1350 << IdxExpr->getSourceRange(); 1351 return; 1352 } 1353 Ty = getFunctionOrMethodResultType(d); 1354 if (!isNSStringType(Ty, S.Context) && 1355 !isCFStringType(Ty, S.Context) && 1356 (!Ty->isPointerType() || 1357 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1358 // FIXME: Should highlight the actual expression that has the wrong type. 1359 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1360 << (not_nsstring_type ? "string type" : "NSString") 1361 << IdxExpr->getSourceRange(); 1362 return; 1363 } 1364 1365 d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, Idx.getZExtValue())); 1366} 1367 1368enum FormatAttrKind { 1369 CFStringFormat, 1370 NSStringFormat, 1371 StrftimeFormat, 1372 SupportedFormat, 1373 IgnoredFormat, 1374 InvalidFormat 1375}; 1376 1377/// getFormatAttrKind - Map from format attribute names to supported format 1378/// types. 1379static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 1380 // Check for formats that get handled specially. 1381 if (Format == "NSString") 1382 return NSStringFormat; 1383 if (Format == "CFString") 1384 return CFStringFormat; 1385 if (Format == "strftime") 1386 return StrftimeFormat; 1387 1388 // Otherwise, check for supported formats. 1389 if (Format == "scanf" || Format == "printf" || Format == "printf0" || 1390 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 1391 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 1392 Format == "zcmn_err") 1393 return SupportedFormat; 1394 1395 if (Format == "gcc_diag" || Format == "gcc_cdiag" || 1396 Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 1397 return IgnoredFormat; 1398 1399 return InvalidFormat; 1400} 1401 1402/// Handle __attribute__((init_priority(priority))) attributes based on 1403/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 1404static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 1405 Sema &S) { 1406 if (!S.getLangOptions().CPlusPlus) { 1407 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1408 return; 1409 } 1410 1411 if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) { 1412 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1413 Attr.setInvalid(); 1414 return; 1415 } 1416 QualType T = dyn_cast<VarDecl>(d)->getType(); 1417 if (S.Context.getAsArrayType(T)) 1418 T = S.Context.getBaseElementType(T); 1419 if (!T->getAs<RecordType>()) { 1420 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1421 Attr.setInvalid(); 1422 return; 1423 } 1424 1425 if (Attr.getNumArgs() != 1) { 1426 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1427 Attr.setInvalid(); 1428 return; 1429 } 1430 Expr *priorityExpr = static_cast<Expr *>(Attr.getArg(0)); 1431 1432 llvm::APSInt priority(32); 1433 if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 1434 !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 1435 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1436 << "init_priority" << priorityExpr->getSourceRange(); 1437 Attr.setInvalid(); 1438 return; 1439 } 1440 unsigned prioritynum = priority.getZExtValue(); 1441 if (prioritynum < 101 || prioritynum > 65535) { 1442 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 1443 << priorityExpr->getSourceRange(); 1444 Attr.setInvalid(); 1445 return; 1446 } 1447 d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, prioritynum)); 1448} 1449 1450/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1451/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1452static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1453 1454 if (!Attr.getParameterName()) { 1455 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1456 << "format" << 1; 1457 return; 1458 } 1459 1460 if (Attr.getNumArgs() != 2) { 1461 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1462 return; 1463 } 1464 1465 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1466 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1467 << Attr.getName() << 0 /*function*/; 1468 return; 1469 } 1470 1471 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1472 unsigned FirstIdx = 1; 1473 1474 llvm::StringRef Format = Attr.getParameterName()->getName(); 1475 1476 // Normalize the argument, __foo__ becomes foo. 1477 if (Format.startswith("__") && Format.endswith("__")) 1478 Format = Format.substr(2, Format.size() - 4); 1479 1480 // Check for supported formats. 1481 FormatAttrKind Kind = getFormatAttrKind(Format); 1482 1483 if (Kind == IgnoredFormat) 1484 return; 1485 1486 if (Kind == InvalidFormat) { 1487 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1488 << "format" << Attr.getParameterName()->getName(); 1489 return; 1490 } 1491 1492 // checks for the 2nd argument 1493 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1494 llvm::APSInt Idx(32); 1495 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1496 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1497 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1498 << "format" << 2 << IdxExpr->getSourceRange(); 1499 return; 1500 } 1501 1502 // FIXME: We should handle the implicit 'this' parameter in a more generic 1503 // way that can be used for other arguments. 1504 bool HasImplicitThisParam = false; 1505 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 1506 if (MD->isInstance()) { 1507 HasImplicitThisParam = true; 1508 NumArgs++; 1509 } 1510 } 1511 1512 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1513 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1514 << "format" << 2 << IdxExpr->getSourceRange(); 1515 return; 1516 } 1517 1518 // FIXME: Do we need to bounds check? 1519 unsigned ArgIdx = Idx.getZExtValue() - 1; 1520 1521 if (HasImplicitThisParam) { 1522 if (ArgIdx == 0) { 1523 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1524 << "a string type" << IdxExpr->getSourceRange(); 1525 return; 1526 } 1527 ArgIdx--; 1528 } 1529 1530 // make sure the format string is really a string 1531 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1532 1533 if (Kind == CFStringFormat) { 1534 if (!isCFStringType(Ty, S.Context)) { 1535 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1536 << "a CFString" << IdxExpr->getSourceRange(); 1537 return; 1538 } 1539 } else if (Kind == NSStringFormat) { 1540 // FIXME: do we need to check if the type is NSString*? What are the 1541 // semantics? 1542 if (!isNSStringType(Ty, S.Context)) { 1543 // FIXME: Should highlight the actual expression that has the wrong type. 1544 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1545 << "an NSString" << IdxExpr->getSourceRange(); 1546 return; 1547 } 1548 } else if (!Ty->isPointerType() || 1549 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1550 // FIXME: Should highlight the actual expression that has the wrong type. 1551 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1552 << "a string type" << IdxExpr->getSourceRange(); 1553 return; 1554 } 1555 1556 // check the 3rd argument 1557 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1558 llvm::APSInt FirstArg(32); 1559 if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 1560 !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1561 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1562 << "format" << 3 << FirstArgExpr->getSourceRange(); 1563 return; 1564 } 1565 1566 // check if the function is variadic if the 3rd argument non-zero 1567 if (FirstArg != 0) { 1568 if (isFunctionOrMethodVariadic(d)) { 1569 ++NumArgs; // +1 for ... 1570 } else { 1571 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1572 return; 1573 } 1574 } 1575 1576 // strftime requires FirstArg to be 0 because it doesn't read from any 1577 // variable the input is just the current time + the format string. 1578 if (Kind == StrftimeFormat) { 1579 if (FirstArg != 0) { 1580 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1581 << FirstArgExpr->getSourceRange(); 1582 return; 1583 } 1584 // if 0 it disables parameter checking (to use with e.g. va_list) 1585 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1586 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1587 << "format" << 3 << FirstArgExpr->getSourceRange(); 1588 return; 1589 } 1590 1591 d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format, 1592 Idx.getZExtValue(), 1593 FirstArg.getZExtValue())); 1594} 1595 1596static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1597 Sema &S) { 1598 // check the attribute arguments. 1599 if (Attr.getNumArgs() != 0) { 1600 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1601 return; 1602 } 1603 1604 // Try to find the underlying union declaration. 1605 RecordDecl *RD = 0; 1606 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1607 if (TD && TD->getUnderlyingType()->isUnionType()) 1608 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1609 else 1610 RD = dyn_cast<RecordDecl>(d); 1611 1612 if (!RD || !RD->isUnion()) { 1613 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1614 << Attr.getName() << 1 /*union*/; 1615 return; 1616 } 1617 1618 if (!RD->isDefinition()) { 1619 S.Diag(Attr.getLoc(), 1620 diag::warn_transparent_union_attribute_not_definition); 1621 return; 1622 } 1623 1624 RecordDecl::field_iterator Field = RD->field_begin(), 1625 FieldEnd = RD->field_end(); 1626 if (Field == FieldEnd) { 1627 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1628 return; 1629 } 1630 1631 FieldDecl *FirstField = *Field; 1632 QualType FirstType = FirstField->getType(); 1633 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 1634 S.Diag(FirstField->getLocation(), 1635 diag::warn_transparent_union_attribute_floating) 1636 << FirstType->isVectorType() << FirstType; 1637 return; 1638 } 1639 1640 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1641 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1642 for (; Field != FieldEnd; ++Field) { 1643 QualType FieldType = Field->getType(); 1644 if (S.Context.getTypeSize(FieldType) != FirstSize || 1645 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1646 // Warn if we drop the attribute. 1647 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1648 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1649 : S.Context.getTypeAlign(FieldType); 1650 S.Diag(Field->getLocation(), 1651 diag::warn_transparent_union_attribute_field_size_align) 1652 << isSize << Field->getDeclName() << FieldBits; 1653 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1654 S.Diag(FirstField->getLocation(), 1655 diag::note_transparent_union_first_field_size_align) 1656 << isSize << FirstBits; 1657 return; 1658 } 1659 } 1660 1661 RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context)); 1662} 1663 1664static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1665 // check the attribute arguments. 1666 if (Attr.getNumArgs() != 1) { 1667 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1668 return; 1669 } 1670 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1671 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1672 1673 // Make sure that there is a string literal as the annotation's single 1674 // argument. 1675 if (!SE) { 1676 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 1677 return; 1678 } 1679 d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString())); 1680} 1681 1682static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1683 // check the attribute arguments. 1684 if (Attr.getNumArgs() > 1) { 1685 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1686 return; 1687 } 1688 1689 //FIXME: The C++0x version of this attribute has more limited applicabilty 1690 // than GNU's, and should error out when it is used to specify a 1691 // weaker alignment, rather than being silently ignored. 1692 1693 if (Attr.getNumArgs() == 0) { 1694 D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0)); 1695 return; 1696 } 1697 1698 S.AddAlignedAttr(Attr.getLoc(), D, static_cast<Expr *>(Attr.getArg(0))); 1699} 1700 1701void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { 1702 if (E->isTypeDependent() || E->isValueDependent()) { 1703 // Save dependent expressions in the AST to be instantiated. 1704 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 1705 return; 1706 } 1707 1708 // FIXME: Cache the number on the Attr object? 1709 llvm::APSInt Alignment(32); 1710 if (!E->isIntegerConstantExpr(Alignment, Context)) { 1711 Diag(AttrLoc, diag::err_attribute_argument_not_int) 1712 << "aligned" << E->getSourceRange(); 1713 return; 1714 } 1715 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1716 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 1717 << E->getSourceRange(); 1718 return; 1719 } 1720 1721 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 1722} 1723 1724void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) { 1725 // FIXME: Cache the number on the Attr object if non-dependent? 1726 // FIXME: Perform checking of type validity 1727 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS)); 1728 return; 1729} 1730 1731/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1732/// type. 1733/// 1734/// Despite what would be logical, the mode attribute is a decl attribute, not a 1735/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1736/// HImode, not an intermediate pointer. 1737static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1738 // This attribute isn't documented, but glibc uses it. It changes 1739 // the width of an int or unsigned int to the specified size. 1740 1741 // Check that there aren't any arguments 1742 if (Attr.getNumArgs() != 0) { 1743 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1744 return; 1745 } 1746 1747 IdentifierInfo *Name = Attr.getParameterName(); 1748 if (!Name) { 1749 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1750 return; 1751 } 1752 1753 llvm::StringRef Str = Attr.getParameterName()->getName(); 1754 1755 // Normalize the attribute name, __foo__ becomes foo. 1756 if (Str.startswith("__") && Str.endswith("__")) 1757 Str = Str.substr(2, Str.size() - 4); 1758 1759 unsigned DestWidth = 0; 1760 bool IntegerMode = true; 1761 bool ComplexMode = false; 1762 switch (Str.size()) { 1763 case 2: 1764 switch (Str[0]) { 1765 case 'Q': DestWidth = 8; break; 1766 case 'H': DestWidth = 16; break; 1767 case 'S': DestWidth = 32; break; 1768 case 'D': DestWidth = 64; break; 1769 case 'X': DestWidth = 96; break; 1770 case 'T': DestWidth = 128; break; 1771 } 1772 if (Str[1] == 'F') { 1773 IntegerMode = false; 1774 } else if (Str[1] == 'C') { 1775 IntegerMode = false; 1776 ComplexMode = true; 1777 } else if (Str[1] != 'I') { 1778 DestWidth = 0; 1779 } 1780 break; 1781 case 4: 1782 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1783 // pointer on PIC16 and other embedded platforms. 1784 if (Str == "word") 1785 DestWidth = S.Context.Target.getPointerWidth(0); 1786 else if (Str == "byte") 1787 DestWidth = S.Context.Target.getCharWidth(); 1788 break; 1789 case 7: 1790 if (Str == "pointer") 1791 DestWidth = S.Context.Target.getPointerWidth(0); 1792 break; 1793 } 1794 1795 QualType OldTy; 1796 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1797 OldTy = TD->getUnderlyingType(); 1798 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1799 OldTy = VD->getType(); 1800 else { 1801 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1802 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1803 return; 1804 } 1805 1806 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 1807 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1808 else if (IntegerMode) { 1809 if (!OldTy->isIntegralOrEnumerationType()) 1810 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1811 } else if (ComplexMode) { 1812 if (!OldTy->isComplexType()) 1813 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1814 } else { 1815 if (!OldTy->isFloatingType()) 1816 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1817 } 1818 1819 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1820 // and friends, at least with glibc. 1821 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1822 // width on unusual platforms. 1823 // FIXME: Make sure floating-point mappings are accurate 1824 // FIXME: Support XF and TF types 1825 QualType NewTy; 1826 switch (DestWidth) { 1827 case 0: 1828 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1829 return; 1830 default: 1831 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1832 return; 1833 case 8: 1834 if (!IntegerMode) { 1835 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1836 return; 1837 } 1838 if (OldTy->isSignedIntegerType()) 1839 NewTy = S.Context.SignedCharTy; 1840 else 1841 NewTy = S.Context.UnsignedCharTy; 1842 break; 1843 case 16: 1844 if (!IntegerMode) { 1845 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1846 return; 1847 } 1848 if (OldTy->isSignedIntegerType()) 1849 NewTy = S.Context.ShortTy; 1850 else 1851 NewTy = S.Context.UnsignedShortTy; 1852 break; 1853 case 32: 1854 if (!IntegerMode) 1855 NewTy = S.Context.FloatTy; 1856 else if (OldTy->isSignedIntegerType()) 1857 NewTy = S.Context.IntTy; 1858 else 1859 NewTy = S.Context.UnsignedIntTy; 1860 break; 1861 case 64: 1862 if (!IntegerMode) 1863 NewTy = S.Context.DoubleTy; 1864 else if (OldTy->isSignedIntegerType()) 1865 if (S.Context.Target.getLongWidth() == 64) 1866 NewTy = S.Context.LongTy; 1867 else 1868 NewTy = S.Context.LongLongTy; 1869 else 1870 if (S.Context.Target.getLongWidth() == 64) 1871 NewTy = S.Context.UnsignedLongTy; 1872 else 1873 NewTy = S.Context.UnsignedLongLongTy; 1874 break; 1875 case 96: 1876 NewTy = S.Context.LongDoubleTy; 1877 break; 1878 case 128: 1879 if (!IntegerMode) { 1880 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1881 return; 1882 } 1883 if (OldTy->isSignedIntegerType()) 1884 NewTy = S.Context.Int128Ty; 1885 else 1886 NewTy = S.Context.UnsignedInt128Ty; 1887 break; 1888 } 1889 1890 if (ComplexMode) { 1891 NewTy = S.Context.getComplexType(NewTy); 1892 } 1893 1894 // Install the new type. 1895 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1896 // FIXME: preserve existing source info. 1897 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 1898 } else 1899 cast<ValueDecl>(D)->setType(NewTy); 1900} 1901 1902static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1903 // check the attribute arguments. 1904 if (Attr.getNumArgs() > 0) { 1905 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1906 return; 1907 } 1908 1909 if (!isFunctionOrMethod(d)) { 1910 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1911 << Attr.getName() << 0 /*function*/; 1912 return; 1913 } 1914 1915 d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context)); 1916} 1917 1918static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1919 // check the attribute arguments. 1920 if (Attr.getNumArgs() != 0) { 1921 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1922 return; 1923 } 1924 1925 if (!isa<FunctionDecl>(d)) { 1926 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1927 << Attr.getName() << 0 /*function*/; 1928 return; 1929 } 1930 1931 d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context)); 1932} 1933 1934static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr, 1935 Sema &S) { 1936 // check the attribute arguments. 1937 if (Attr.getNumArgs() != 0) { 1938 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1939 return; 1940 } 1941 1942 if (!isa<FunctionDecl>(d)) { 1943 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1944 << Attr.getName() << 0 /*function*/; 1945 return; 1946 } 1947 1948 d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), S.Context)); 1949} 1950 1951static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1952 // check the attribute arguments. 1953 if (Attr.getNumArgs() != 0) { 1954 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1955 return; 1956 } 1957 1958 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1959 if (Fn == 0) { 1960 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1961 << Attr.getName() << 0 /*function*/; 1962 return; 1963 } 1964 1965 if (!Fn->isInlineSpecified()) { 1966 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1967 return; 1968 } 1969 1970 d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context)); 1971} 1972 1973static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1974 // Diagnostic is emitted elsewhere: here we store the (valid) Attr 1975 // in the Decl node for syntactic reasoning, e.g., pretty-printing. 1976 assert(Attr.isInvalid() == false); 1977 1978 switch (Attr.getKind()) { 1979 case AttributeList::AT_fastcall: 1980 d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context)); 1981 return; 1982 case AttributeList::AT_stdcall: 1983 d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context)); 1984 return; 1985 case AttributeList::AT_thiscall: 1986 d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context)); 1987 case AttributeList::AT_cdecl: 1988 d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context)); 1989 return; 1990 default: 1991 llvm_unreachable("unexpected attribute kind"); 1992 return; 1993 } 1994} 1995 1996static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1997 // check the attribute arguments. 1998 if (Attr.getNumArgs() != 1) { 1999 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2000 return; 2001 } 2002 2003 if (!isFunctionOrMethod(d)) { 2004 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2005 << Attr.getName() << 0 /*function*/; 2006 return; 2007 } 2008 2009 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 2010 llvm::APSInt NumParams(32); 2011 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 2012 !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 2013 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 2014 << "regparm" << NumParamsExpr->getSourceRange(); 2015 return; 2016 } 2017 2018 if (S.Context.Target.getRegParmMax() == 0) { 2019 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 2020 << NumParamsExpr->getSourceRange(); 2021 return; 2022 } 2023 2024 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 2025 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 2026 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 2027 return; 2028 } 2029 2030 d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, 2031 NumParams.getZExtValue())); 2032} 2033 2034static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2035 // check the attribute arguments. 2036 if (Attr.getNumArgs() != 0) { 2037 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2038 return; 2039 } 2040 2041 if (!isa<CXXRecordDecl>(d) 2042 && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 2043 S.Diag(Attr.getLoc(), 2044 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2045 : diag::warn_attribute_wrong_decl_type) 2046 << Attr.getName() << 7 /*virtual method or class*/; 2047 return; 2048 } 2049 2050 // FIXME: Conform to C++0x redeclaration rules. 2051 2052 if (d->getAttr<FinalAttr>()) { 2053 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 2054 return; 2055 } 2056 2057 d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context)); 2058} 2059 2060//===----------------------------------------------------------------------===// 2061// C++0x member checking attributes 2062//===----------------------------------------------------------------------===// 2063 2064static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2065 if (Attr.getNumArgs() != 0) { 2066 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2067 return; 2068 } 2069 2070 if (!isa<CXXRecordDecl>(d)) { 2071 S.Diag(Attr.getLoc(), 2072 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2073 : diag::warn_attribute_wrong_decl_type) 2074 << Attr.getName() << 9 /*class*/; 2075 return; 2076 } 2077 2078 if (d->getAttr<BaseCheckAttr>()) { 2079 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 2080 return; 2081 } 2082 2083 d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context)); 2084} 2085 2086static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2087 if (Attr.getNumArgs() != 0) { 2088 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2089 return; 2090 } 2091 2092 if (!isa<RecordDecl>(d->getDeclContext())) { 2093 // FIXME: It's not the type that's the problem 2094 S.Diag(Attr.getLoc(), 2095 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2096 : diag::warn_attribute_wrong_decl_type) 2097 << Attr.getName() << 11 /*member*/; 2098 return; 2099 } 2100 2101 // FIXME: Conform to C++0x redeclaration rules. 2102 2103 if (d->getAttr<HidingAttr>()) { 2104 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 2105 return; 2106 } 2107 2108 d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context)); 2109} 2110 2111static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2112 if (Attr.getNumArgs() != 0) { 2113 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2114 return; 2115 } 2116 2117 if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 2118 // FIXME: It's not the type that's the problem 2119 S.Diag(Attr.getLoc(), 2120 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2121 : diag::warn_attribute_wrong_decl_type) 2122 << Attr.getName() << 10 /*virtual method*/; 2123 return; 2124 } 2125 2126 // FIXME: Conform to C++0x redeclaration rules. 2127 2128 if (d->getAttr<OverrideAttr>()) { 2129 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 2130 return; 2131 } 2132 2133 d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context)); 2134} 2135 2136//===----------------------------------------------------------------------===// 2137// Checker-specific attribute handlers. 2138//===----------------------------------------------------------------------===// 2139 2140static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 2141 Sema &S) { 2142 2143 QualType RetTy; 2144 2145 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 2146 RetTy = MD->getResultType(); 2147 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 2148 RetTy = FD->getResultType(); 2149 else { 2150 SourceLocation L = Attr.getLoc(); 2151 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 2152 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 2153 return; 2154 } 2155 2156 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 2157 || RetTy->getAs<ObjCObjectPointerType>())) { 2158 SourceLocation L = Attr.getLoc(); 2159 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 2160 << SourceRange(L, L) << Attr.getName(); 2161 return; 2162 } 2163 2164 switch (Attr.getKind()) { 2165 default: 2166 assert(0 && "invalid ownership attribute"); 2167 return; 2168 case AttributeList::AT_cf_returns_not_retained: 2169 d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), S.Context)); 2170 return; 2171 case AttributeList::AT_ns_returns_not_retained: 2172 d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), S.Context)); 2173 return; 2174 case AttributeList::AT_cf_returns_retained: 2175 d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), S.Context)); 2176 return; 2177 case AttributeList::AT_ns_returns_retained: 2178 d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), S.Context)); 2179 return; 2180 }; 2181} 2182 2183static bool isKnownDeclSpecAttr(const AttributeList &Attr) { 2184 return Attr.getKind() == AttributeList::AT_dllimport || 2185 Attr.getKind() == AttributeList::AT_dllexport; 2186} 2187 2188//===----------------------------------------------------------------------===// 2189// Top Level Sema Entry Points 2190//===----------------------------------------------------------------------===// 2191 2192/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 2193/// the attribute applies to decls. If the attribute is a type attribute, just 2194/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 2195/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 2196static void ProcessDeclAttribute(Scope *scope, Decl *D, 2197 const AttributeList &Attr, Sema &S) { 2198 if (Attr.isInvalid()) 2199 return; 2200 2201 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 2202 // FIXME: Try to deal with other __declspec attributes! 2203 return; 2204 switch (Attr.getKind()) { 2205 case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 2206 case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 2207 case AttributeList::AT_IBOutletCollection: 2208 HandleIBOutletCollection(D, Attr, S); break; 2209 case AttributeList::AT_address_space: 2210 case AttributeList::AT_objc_gc: 2211 case AttributeList::AT_vector_size: 2212 // Ignore these, these are type attributes, handled by 2213 // ProcessTypeAttributes. 2214 break; 2215 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 2216 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 2217 case AttributeList::AT_always_inline: 2218 HandleAlwaysInlineAttr (D, Attr, S); break; 2219 case AttributeList::AT_analyzer_noreturn: 2220 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 2221 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 2222 case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 2223 case AttributeList::AT_carries_dependency: 2224 HandleDependencyAttr (D, Attr, S); break; 2225 case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 2226 case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 2227 case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 2228 case AttributeList::AT_ext_vector_type: 2229 HandleExtVectorTypeAttr(scope, D, Attr, S); 2230 break; 2231 case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 2232 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 2233 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 2234 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 2235 case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 2236 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 2237 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 2238 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 2239 case AttributeList::AT_ownership_returns: 2240 case AttributeList::AT_ownership_takes: 2241 case AttributeList::AT_ownership_holds: 2242 HandleOwnershipAttr (D, Attr, S); break; 2243 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 2244 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 2245 case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 2246 case AttributeList::AT_vecreturn: HandleVecReturnAttr (D, Attr, S); break; 2247 2248 // Checker-specific. 2249 case AttributeList::AT_ns_returns_not_retained: 2250 case AttributeList::AT_cf_returns_not_retained: 2251 case AttributeList::AT_ns_returns_retained: 2252 case AttributeList::AT_cf_returns_retained: 2253 HandleNSReturnsRetainedAttr(D, Attr, S); break; 2254 2255 case AttributeList::AT_reqd_wg_size: 2256 HandleReqdWorkGroupSize(D, Attr, S); break; 2257 2258 case AttributeList::AT_init_priority: 2259 HandleInitPriorityAttr(D, Attr, S); break; 2260 2261 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 2262 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 2263 case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 2264 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 2265 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 2266 case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 2267 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 2268 break; 2269 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 2270 case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 2271 case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 2272 case AttributeList::AT_transparent_union: 2273 HandleTransparentUnionAttr(D, Attr, S); 2274 break; 2275 case AttributeList::AT_objc_exception: 2276 HandleObjCExceptionAttr(D, Attr, S); 2277 break; 2278 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 2279 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 2280 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 2281 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 2282 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 2283 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 2284 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 2285 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 2286 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 2287 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 2288 case AttributeList::IgnoredAttribute: 2289 // Just ignore 2290 break; 2291 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 2292 HandleNoInstrumentFunctionAttr(D, Attr, S); 2293 break; 2294 case AttributeList::AT_stdcall: 2295 case AttributeList::AT_cdecl: 2296 case AttributeList::AT_fastcall: 2297 case AttributeList::AT_thiscall: 2298 HandleCallConvAttr(D, Attr, S); 2299 break; 2300 default: 2301 // Ask target about the attribute. 2302 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 2303 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 2304 S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 2305 << Attr.getName(); 2306 break; 2307 } 2308} 2309 2310/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 2311/// attribute list to the specified decl, ignoring any type attributes. 2312void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 2313 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 2314 ProcessDeclAttribute(S, D, *l, *this); 2315 } 2316 2317 // GCC accepts 2318 // static int a9 __attribute__((weakref)); 2319 // but that looks really pointless. We reject it. 2320 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 2321 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 2322 dyn_cast<NamedDecl>(D)->getNameAsString(); 2323 return; 2324 } 2325} 2326 2327/// DeclClonePragmaWeak - clone existing decl (maybe definition), 2328/// #pragma weak needs a non-definition decl and source may not have one 2329NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 2330 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 2331 NamedDecl *NewD = 0; 2332 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 2333 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 2334 FD->getLocation(), DeclarationName(II), 2335 FD->getType(), FD->getTypeSourceInfo()); 2336 if (FD->getQualifier()) { 2337 FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 2338 NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 2339 } 2340 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 2341 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 2342 VD->getLocation(), II, 2343 VD->getType(), VD->getTypeSourceInfo(), 2344 VD->getStorageClass(), 2345 VD->getStorageClassAsWritten()); 2346 if (VD->getQualifier()) { 2347 VarDecl *NewVD = cast<VarDecl>(NewD); 2348 NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 2349 } 2350 } 2351 return NewD; 2352} 2353 2354/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 2355/// applied to it, possibly with an alias. 2356void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 2357 if (W.getUsed()) return; // only do this once 2358 W.setUsed(true); 2359 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 2360 IdentifierInfo *NDId = ND->getIdentifier(); 2361 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 2362 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 2363 NDId->getName())); 2364 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2365 WeakTopLevelDecl.push_back(NewD); 2366 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 2367 // to insert Decl at TU scope, sorry. 2368 DeclContext *SavedContext = CurContext; 2369 CurContext = Context.getTranslationUnitDecl(); 2370 PushOnScopeChains(NewD, S); 2371 CurContext = SavedContext; 2372 } else { // just add weak to existing 2373 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2374 } 2375} 2376 2377/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 2378/// it, apply them to D. This is a bit tricky because PD can have attributes 2379/// specified in many different places, and we need to find and apply them all. 2380void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 2381 // Handle #pragma weak 2382 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 2383 if (ND->hasLinkage()) { 2384 WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 2385 if (W != WeakInfo()) { 2386 // Identifier referenced by #pragma weak before it was declared 2387 DeclApplyPragmaWeak(S, ND, W); 2388 WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 2389 } 2390 } 2391 } 2392 2393 // Apply decl attributes from the DeclSpec if present. 2394 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 2395 ProcessDeclAttributeList(S, D, Attrs); 2396 2397 // Walk the declarator structure, applying decl attributes that were in a type 2398 // position to the decl itself. This handles cases like: 2399 // int *__attr__(x)** D; 2400 // when X is a decl attribute. 2401 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 2402 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 2403 ProcessDeclAttributeList(S, D, Attrs); 2404 2405 // Finally, apply any attributes on the decl itself. 2406 if (const AttributeList *Attrs = PD.getAttributes()) 2407 ProcessDeclAttributeList(S, D, Attrs); 2408} 2409 2410/// PushParsingDeclaration - Enter a new "scope" of deprecation 2411/// warnings. 2412/// 2413/// The state token we use is the start index of this scope 2414/// on the warning stack. 2415Action::ParsingDeclStackState Sema::PushParsingDeclaration() { 2416 ParsingDeclDepth++; 2417 return (ParsingDeclStackState) DelayedDiagnostics.size(); 2418} 2419 2420void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) { 2421 assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 2422 ParsingDeclDepth--; 2423 2424 if (DelayedDiagnostics.empty()) 2425 return; 2426 2427 unsigned SavedIndex = (unsigned) S; 2428 assert(SavedIndex <= DelayedDiagnostics.size() && 2429 "saved index is out of bounds"); 2430 2431 unsigned E = DelayedDiagnostics.size(); 2432 2433 // We only want to actually emit delayed diagnostics when we 2434 // successfully parsed a decl. 2435 Decl *D = Ctx ? Ctx.getAs<Decl>() : 0; 2436 if (D) { 2437 // We really do want to start with 0 here. We get one push for a 2438 // decl spec and another for each declarator; in a decl group like: 2439 // deprecated_typedef foo, *bar, baz(); 2440 // only the declarator pops will be passed decls. This is correct; 2441 // we really do need to consider delayed diagnostics from the decl spec 2442 // for each of the different declarations. 2443 for (unsigned I = 0; I != E; ++I) { 2444 if (DelayedDiagnostics[I].Triggered) 2445 continue; 2446 2447 switch (DelayedDiagnostics[I].Kind) { 2448 case DelayedDiagnostic::Deprecation: 2449 HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 2450 break; 2451 2452 case DelayedDiagnostic::Access: 2453 HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 2454 break; 2455 } 2456 } 2457 } 2458 2459 // Destroy all the delayed diagnostics we're about to pop off. 2460 for (unsigned I = SavedIndex; I != E; ++I) 2461 DelayedDiagnostics[I].destroy(); 2462 2463 DelayedDiagnostics.set_size(SavedIndex); 2464} 2465 2466static bool isDeclDeprecated(Decl *D) { 2467 do { 2468 if (D->hasAttr<DeprecatedAttr>()) 2469 return true; 2470 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 2471 return false; 2472} 2473 2474void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD, 2475 Decl *Ctx) { 2476 if (isDeclDeprecated(Ctx)) 2477 return; 2478 2479 DD.Triggered = true; 2480 Diag(DD.Loc, diag::warn_deprecated) 2481 << DD.DeprecationData.Decl->getDeclName(); 2482} 2483 2484void Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) { 2485 // Delay if we're currently parsing a declaration. 2486 if (ParsingDeclDepth) { 2487 DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D)); 2488 return; 2489 } 2490 2491 // Otherwise, don't warn if our current context is deprecated. 2492 if (isDeclDeprecated(cast<Decl>(CurContext))) 2493 return; 2494 2495 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 2496} 2497