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