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