SemaDeclAttr.cpp revision 15e14a289583616e582a23b320933e846a742626
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 HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 889 if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 890 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 891 << Attr.getName() << 8 /*function, method, or parameter*/; 892 return; 893 } 894 // FIXME: Actually store the attribute on the declaration 895} 896 897static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 898 // check the attribute arguments. 899 if (Attr.getNumArgs() != 0) { 900 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 901 return; 902 } 903 904 if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) && 905 !isa<TypeDecl>(d)) { 906 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 907 << Attr.getName() << 2 /*variable and function*/; 908 return; 909 } 910 911 d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context)); 912} 913 914static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 915 // check the attribute arguments. 916 if (Attr.getNumArgs() != 0) { 917 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 918 return; 919 } 920 921 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 922 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 923 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 924 return; 925 } 926 } else if (!isFunctionOrMethod(d)) { 927 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 928 << Attr.getName() << 2 /*variable and function*/; 929 return; 930 } 931 932 d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 933} 934 935static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 936 // check the attribute arguments. 937 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 938 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 939 << "0 or 1"; 940 return; 941 } 942 943 int priority = 65535; // FIXME: Do not hardcode such constants. 944 if (Attr.getNumArgs() > 0) { 945 Expr *E = Attr.getArg(0); 946 llvm::APSInt Idx(32); 947 if (E->isTypeDependent() || E->isValueDependent() || 948 !E->isIntegerConstantExpr(Idx, S.Context)) { 949 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 950 << "constructor" << 1 << E->getSourceRange(); 951 return; 952 } 953 priority = Idx.getZExtValue(); 954 } 955 956 if (!isa<FunctionDecl>(d)) { 957 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 958 << Attr.getName() << 0 /*function*/; 959 return; 960 } 961 962 d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, 963 priority)); 964} 965 966static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 967 // check the attribute arguments. 968 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 969 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 970 << "0 or 1"; 971 return; 972 } 973 974 int priority = 65535; // FIXME: Do not hardcode such constants. 975 if (Attr.getNumArgs() > 0) { 976 Expr *E = Attr.getArg(0); 977 llvm::APSInt Idx(32); 978 if (E->isTypeDependent() || E->isValueDependent() || 979 !E->isIntegerConstantExpr(Idx, S.Context)) { 980 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 981 << "destructor" << 1 << E->getSourceRange(); 982 return; 983 } 984 priority = Idx.getZExtValue(); 985 } 986 987 if (!isa<FunctionDecl>(d)) { 988 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 989 << Attr.getName() << 0 /*function*/; 990 return; 991 } 992 993 d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, 994 priority)); 995} 996 997static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 998 // check the attribute arguments. 999 int noArgs = Attr.getNumArgs(); 1000 if (noArgs > 1) { 1001 S.Diag(Attr.getLoc(), 1002 diag::err_attribute_wrong_number_arguments) << "0 or 1"; 1003 return; 1004 } 1005 // Handle the case where deprecated attribute has a text message. 1006 StringLiteral *SE; 1007 if (noArgs == 1) { 1008 Expr *ArgExpr = Attr.getArg(0); 1009 SE = dyn_cast<StringLiteral>(ArgExpr); 1010 if (!SE) { 1011 S.Diag(ArgExpr->getLocStart(), 1012 diag::err_attribute_not_string) << "deprecated"; 1013 return; 1014 } 1015 } 1016 else 1017 SE = StringLiteral::CreateEmpty(S.Context, 1); 1018 1019 d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, 1020 SE->getString())); 1021} 1022 1023static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1024 // check the attribute arguments. 1025 int noArgs = Attr.getNumArgs(); 1026 if (noArgs > 1) { 1027 S.Diag(Attr.getLoc(), 1028 diag::err_attribute_wrong_number_arguments) << "0 or 1"; 1029 return; 1030 } 1031 // Handle the case where unavailable attribute has a text message. 1032 StringLiteral *SE; 1033 if (noArgs == 1) { 1034 Expr *ArgExpr = Attr.getArg(0); 1035 SE = dyn_cast<StringLiteral>(ArgExpr); 1036 if (!SE) { 1037 S.Diag(ArgExpr->getLocStart(), 1038 diag::err_attribute_not_string) << "unavailable"; 1039 return; 1040 } 1041 } 1042 else 1043 SE = StringLiteral::CreateEmpty(S.Context, 1); 1044 d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, 1045 SE->getString())); 1046} 1047 1048static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1049 // check the attribute arguments. 1050 if (Attr.getNumArgs() != 1) { 1051 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1052 return; 1053 } 1054 1055 Expr *Arg = Attr.getArg(0); 1056 Arg = Arg->IgnoreParenCasts(); 1057 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1058 1059 if (Str == 0 || Str->isWide()) { 1060 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1061 << "visibility" << 1; 1062 return; 1063 } 1064 1065 llvm::StringRef TypeStr = Str->getString(); 1066 VisibilityAttr::VisibilityType type; 1067 1068 if (TypeStr == "default") 1069 type = VisibilityAttr::Default; 1070 else if (TypeStr == "hidden") 1071 type = VisibilityAttr::Hidden; 1072 else if (TypeStr == "internal") 1073 type = VisibilityAttr::Hidden; // FIXME 1074 else if (TypeStr == "protected") 1075 type = VisibilityAttr::Protected; 1076 else { 1077 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 1078 return; 1079 } 1080 1081 d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type)); 1082} 1083 1084static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 1085 Sema &S) { 1086 if (Attr.getNumArgs() != 0) { 1087 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1088 return; 1089 } 1090 1091 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 1092 if (OCI == 0) { 1093 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 1094 return; 1095 } 1096 1097 D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context)); 1098} 1099 1100static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 1101 if (Attr.getNumArgs() != 0) { 1102 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1103 return; 1104 } 1105 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1106 QualType T = TD->getUnderlyingType(); 1107 if (!T->isPointerType() || 1108 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 1109 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 1110 return; 1111 } 1112 } 1113 D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context)); 1114} 1115 1116static void 1117HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1118 if (Attr.getNumArgs() != 0) { 1119 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1120 return; 1121 } 1122 1123 if (!isa<FunctionDecl>(D)) { 1124 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 1125 return; 1126 } 1127 1128 D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context)); 1129} 1130 1131static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1132 if (!Attr.getParameterName()) { 1133 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1134 << "blocks" << 1; 1135 return; 1136 } 1137 1138 if (Attr.getNumArgs() != 0) { 1139 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1140 return; 1141 } 1142 1143 BlocksAttr::BlockType type; 1144 if (Attr.getParameterName()->isStr("byref")) 1145 type = BlocksAttr::ByRef; 1146 else { 1147 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1148 << "blocks" << Attr.getParameterName(); 1149 return; 1150 } 1151 1152 d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type)); 1153} 1154 1155static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1156 // check the attribute arguments. 1157 if (Attr.getNumArgs() > 2) { 1158 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 1159 << "0, 1 or 2"; 1160 return; 1161 } 1162 1163 int sentinel = 0; 1164 if (Attr.getNumArgs() > 0) { 1165 Expr *E = Attr.getArg(0); 1166 llvm::APSInt Idx(32); 1167 if (E->isTypeDependent() || E->isValueDependent() || 1168 !E->isIntegerConstantExpr(Idx, S.Context)) { 1169 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1170 << "sentinel" << 1 << E->getSourceRange(); 1171 return; 1172 } 1173 sentinel = Idx.getZExtValue(); 1174 1175 if (sentinel < 0) { 1176 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 1177 << E->getSourceRange(); 1178 return; 1179 } 1180 } 1181 1182 int nullPos = 0; 1183 if (Attr.getNumArgs() > 1) { 1184 Expr *E = Attr.getArg(1); 1185 llvm::APSInt Idx(32); 1186 if (E->isTypeDependent() || E->isValueDependent() || 1187 !E->isIntegerConstantExpr(Idx, S.Context)) { 1188 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1189 << "sentinel" << 2 << E->getSourceRange(); 1190 return; 1191 } 1192 nullPos = Idx.getZExtValue(); 1193 1194 if (nullPos > 1 || nullPos < 0) { 1195 // FIXME: This error message could be improved, it would be nice 1196 // to say what the bounds actually are. 1197 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1198 << E->getSourceRange(); 1199 return; 1200 } 1201 } 1202 1203 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 1204 const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 1205 assert(FT && "FunctionDecl has non-function type?"); 1206 1207 if (isa<FunctionNoProtoType>(FT)) { 1208 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1209 return; 1210 } 1211 1212 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 1213 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1214 return; 1215 } 1216 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 1217 if (!MD->isVariadic()) { 1218 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1219 return; 1220 } 1221 } else if (isa<BlockDecl>(d)) { 1222 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 1223 // caller. 1224 ; 1225 } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 1226 QualType Ty = V->getType(); 1227 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 1228 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 1229 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 1230 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 1231 int m = Ty->isFunctionPointerType() ? 0 : 1; 1232 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 1233 return; 1234 } 1235 } else { 1236 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1237 << Attr.getName() << 6 /*function, method or block */; 1238 return; 1239 } 1240 } else { 1241 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1242 << Attr.getName() << 6 /*function, method or block */; 1243 return; 1244 } 1245 d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, 1246 nullPos)); 1247} 1248 1249static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 1250 // check the attribute arguments. 1251 if (Attr.getNumArgs() != 0) { 1252 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1253 return; 1254 } 1255 1256 if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1257 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1258 << Attr.getName() << 0 /*function*/; 1259 return; 1260 } 1261 1262 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1263 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1264 << Attr.getName() << 0; 1265 return; 1266 } 1267 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1268 if (MD->getResultType()->isVoidType()) { 1269 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1270 << Attr.getName() << 1; 1271 return; 1272 } 1273 1274 D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context)); 1275} 1276 1277static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1278 // check the attribute arguments. 1279 if (Attr.getNumArgs() != 0) { 1280 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1281 return; 1282 } 1283 1284 /* weak only applies to non-static declarations */ 1285 if (isStaticVarOrStaticFunction(D)) { 1286 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 1287 dyn_cast<NamedDecl>(D)->getNameAsString(); 1288 return; 1289 } 1290 1291 // TODO: could also be applied to methods? 1292 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 1293 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1294 << Attr.getName() << 2 /*variable and function*/; 1295 return; 1296 } 1297 1298 D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context)); 1299} 1300 1301static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1302 // check the attribute arguments. 1303 if (Attr.getNumArgs() != 0) { 1304 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1305 return; 1306 } 1307 1308 // weak_import only applies to variable & function declarations. 1309 bool isDef = false; 1310 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 1311 isDef = (!VD->hasExternalStorage() || VD->getInit()); 1312 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1313 isDef = FD->hasBody(); 1314 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 1315 // We ignore weak import on properties and methods 1316 return; 1317 } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) { 1318 // Don't issue the warning for darwin as target; yet, ignore the attribute. 1319 if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin || 1320 !isa<ObjCInterfaceDecl>(D)) 1321 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1322 << Attr.getName() << 2 /*variable and function*/; 1323 return; 1324 } 1325 1326 // Merge should handle any subsequent violations. 1327 if (isDef) { 1328 S.Diag(Attr.getLoc(), 1329 diag::warn_attribute_weak_import_invalid_on_definition) 1330 << "weak_import" << 2 /*variable and function*/; 1331 return; 1332 } 1333 1334 D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context)); 1335} 1336 1337static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 1338 Sema &S) { 1339 // Attribute has 3 arguments. 1340 if (Attr.getNumArgs() != 3) { 1341 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1342 return; 1343 } 1344 1345 unsigned WGSize[3]; 1346 for (unsigned i = 0; i < 3; ++i) { 1347 Expr *E = Attr.getArg(i); 1348 llvm::APSInt ArgNum(32); 1349 if (E->isTypeDependent() || E->isValueDependent() || 1350 !E->isIntegerConstantExpr(ArgNum, S.Context)) { 1351 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1352 << "reqd_work_group_size" << E->getSourceRange(); 1353 return; 1354 } 1355 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 1356 } 1357 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context, 1358 WGSize[0], WGSize[1], 1359 WGSize[2])); 1360} 1361 1362static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1363 // Attribute has no arguments. 1364 if (Attr.getNumArgs() != 1) { 1365 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1366 return; 1367 } 1368 1369 // Make sure that there is a string literal as the sections's single 1370 // argument. 1371 Expr *ArgExpr = Attr.getArg(0); 1372 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1373 if (!SE) { 1374 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 1375 return; 1376 } 1377 1378 // If the target wants to validate the section specifier, make it happen. 1379 std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 1380 if (!Error.empty()) { 1381 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1382 << Error; 1383 return; 1384 } 1385 1386 // This attribute cannot be applied to local variables. 1387 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 1388 S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 1389 return; 1390 } 1391 1392 D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, 1393 SE->getString())); 1394} 1395 1396 1397static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1398 // check the attribute arguments. 1399 if (Attr.getNumArgs() != 0) { 1400 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1401 return; 1402 } 1403 1404 d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context)); 1405} 1406 1407static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1408 // check the attribute arguments. 1409 if (Attr.getNumArgs() != 0) { 1410 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1411 return; 1412 } 1413 1414 d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context)); 1415} 1416 1417static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1418 // check the attribute arguments. 1419 if (Attr.getNumArgs() != 0) { 1420 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1421 return; 1422 } 1423 1424 d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context)); 1425} 1426 1427static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1428 if (!Attr.getParameterName()) { 1429 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1430 return; 1431 } 1432 1433 if (Attr.getNumArgs() != 0) { 1434 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1435 return; 1436 } 1437 1438 VarDecl *VD = dyn_cast<VarDecl>(d); 1439 1440 if (!VD || !VD->hasLocalStorage()) { 1441 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1442 return; 1443 } 1444 1445 // Look up the function 1446 // FIXME: Lookup probably isn't looking in the right place 1447 NamedDecl *CleanupDecl 1448 = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 1449 Attr.getParameterLoc(), Sema::LookupOrdinaryName); 1450 if (!CleanupDecl) { 1451 S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 1452 Attr.getParameterName(); 1453 return; 1454 } 1455 1456 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1457 if (!FD) { 1458 S.Diag(Attr.getParameterLoc(), 1459 diag::err_attribute_cleanup_arg_not_function) 1460 << Attr.getParameterName(); 1461 return; 1462 } 1463 1464 if (FD->getNumParams() != 1) { 1465 S.Diag(Attr.getParameterLoc(), 1466 diag::err_attribute_cleanup_func_must_take_one_arg) 1467 << Attr.getParameterName(); 1468 return; 1469 } 1470 1471 // We're currently more strict than GCC about what function types we accept. 1472 // If this ever proves to be a problem it should be easy to fix. 1473 QualType Ty = S.Context.getPointerType(VD->getType()); 1474 QualType ParamTy = FD->getParamDecl(0)->getType(); 1475 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1476 S.Diag(Attr.getParameterLoc(), 1477 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1478 Attr.getParameterName() << ParamTy << Ty; 1479 return; 1480 } 1481 1482 d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD)); 1483 S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD); 1484} 1485 1486/// Handle __attribute__((format_arg((idx)))) attribute based on 1487/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1488static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1489 if (Attr.getNumArgs() != 1) { 1490 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1491 return; 1492 } 1493 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1494 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1495 << Attr.getName() << 0 /*function*/; 1496 return; 1497 } 1498 1499 // In C++ the implicit 'this' function parameter also counts, and they are 1500 // counted from one. 1501 bool HasImplicitThisParam = isInstanceMethod(d); 1502 unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 1503 unsigned FirstIdx = 1; 1504 1505 // checks for the 2nd argument 1506 Expr *IdxExpr = Attr.getArg(0); 1507 llvm::APSInt Idx(32); 1508 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1509 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1510 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1511 << "format" << 2 << IdxExpr->getSourceRange(); 1512 return; 1513 } 1514 1515 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1516 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1517 << "format" << 2 << IdxExpr->getSourceRange(); 1518 return; 1519 } 1520 1521 unsigned ArgIdx = Idx.getZExtValue() - 1; 1522 1523 if (HasImplicitThisParam) { 1524 if (ArgIdx == 0) { 1525 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 1526 << "format_arg" << IdxExpr->getSourceRange(); 1527 return; 1528 } 1529 ArgIdx--; 1530 } 1531 1532 // make sure the format string is really a string 1533 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1534 1535 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 1536 if (not_nsstring_type && 1537 !isCFStringType(Ty, S.Context) && 1538 (!Ty->isPointerType() || 1539 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1540 // FIXME: Should highlight the actual expression that has the wrong type. 1541 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1542 << (not_nsstring_type ? "a string type" : "an NSString") 1543 << IdxExpr->getSourceRange(); 1544 return; 1545 } 1546 Ty = getFunctionOrMethodResultType(d); 1547 if (!isNSStringType(Ty, S.Context) && 1548 !isCFStringType(Ty, S.Context) && 1549 (!Ty->isPointerType() || 1550 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1551 // FIXME: Should highlight the actual expression that has the wrong type. 1552 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1553 << (not_nsstring_type ? "string type" : "NSString") 1554 << IdxExpr->getSourceRange(); 1555 return; 1556 } 1557 1558 d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, 1559 Idx.getZExtValue())); 1560} 1561 1562enum FormatAttrKind { 1563 CFStringFormat, 1564 NSStringFormat, 1565 StrftimeFormat, 1566 SupportedFormat, 1567 IgnoredFormat, 1568 InvalidFormat 1569}; 1570 1571/// getFormatAttrKind - Map from format attribute names to supported format 1572/// types. 1573static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 1574 // Check for formats that get handled specially. 1575 if (Format == "NSString") 1576 return NSStringFormat; 1577 if (Format == "CFString") 1578 return CFStringFormat; 1579 if (Format == "strftime") 1580 return StrftimeFormat; 1581 1582 // Otherwise, check for supported formats. 1583 if (Format == "scanf" || Format == "printf" || Format == "printf0" || 1584 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 1585 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 1586 Format == "zcmn_err") 1587 return SupportedFormat; 1588 1589 if (Format == "gcc_diag" || Format == "gcc_cdiag" || 1590 Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 1591 return IgnoredFormat; 1592 1593 return InvalidFormat; 1594} 1595 1596/// Handle __attribute__((init_priority(priority))) attributes based on 1597/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 1598static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 1599 Sema &S) { 1600 if (!S.getLangOptions().CPlusPlus) { 1601 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1602 return; 1603 } 1604 1605 if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) { 1606 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1607 Attr.setInvalid(); 1608 return; 1609 } 1610 QualType T = dyn_cast<VarDecl>(d)->getType(); 1611 if (S.Context.getAsArrayType(T)) 1612 T = S.Context.getBaseElementType(T); 1613 if (!T->getAs<RecordType>()) { 1614 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1615 Attr.setInvalid(); 1616 return; 1617 } 1618 1619 if (Attr.getNumArgs() != 1) { 1620 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1621 Attr.setInvalid(); 1622 return; 1623 } 1624 Expr *priorityExpr = Attr.getArg(0); 1625 1626 llvm::APSInt priority(32); 1627 if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 1628 !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 1629 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1630 << "init_priority" << priorityExpr->getSourceRange(); 1631 Attr.setInvalid(); 1632 return; 1633 } 1634 unsigned prioritynum = priority.getZExtValue(); 1635 if (prioritynum < 101 || prioritynum > 65535) { 1636 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 1637 << priorityExpr->getSourceRange(); 1638 Attr.setInvalid(); 1639 return; 1640 } 1641 d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, 1642 prioritynum)); 1643} 1644 1645/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1646/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1647static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1648 1649 if (!Attr.getParameterName()) { 1650 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1651 << "format" << 1; 1652 return; 1653 } 1654 1655 if (Attr.getNumArgs() != 2) { 1656 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1657 return; 1658 } 1659 1660 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1661 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1662 << Attr.getName() << 0 /*function*/; 1663 return; 1664 } 1665 1666 // In C++ the implicit 'this' function parameter also counts, and they are 1667 // counted from one. 1668 bool HasImplicitThisParam = isInstanceMethod(d); 1669 unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 1670 unsigned FirstIdx = 1; 1671 1672 llvm::StringRef Format = Attr.getParameterName()->getName(); 1673 1674 // Normalize the argument, __foo__ becomes foo. 1675 if (Format.startswith("__") && Format.endswith("__")) 1676 Format = Format.substr(2, Format.size() - 4); 1677 1678 // Check for supported formats. 1679 FormatAttrKind Kind = getFormatAttrKind(Format); 1680 1681 if (Kind == IgnoredFormat) 1682 return; 1683 1684 if (Kind == InvalidFormat) { 1685 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1686 << "format" << Attr.getParameterName()->getName(); 1687 return; 1688 } 1689 1690 // checks for the 2nd argument 1691 Expr *IdxExpr = Attr.getArg(0); 1692 llvm::APSInt Idx(32); 1693 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1694 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1695 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1696 << "format" << 2 << IdxExpr->getSourceRange(); 1697 return; 1698 } 1699 1700 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1701 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1702 << "format" << 2 << IdxExpr->getSourceRange(); 1703 return; 1704 } 1705 1706 // FIXME: Do we need to bounds check? 1707 unsigned ArgIdx = Idx.getZExtValue() - 1; 1708 1709 if (HasImplicitThisParam) { 1710 if (ArgIdx == 0) { 1711 S.Diag(Attr.getLoc(), 1712 diag::err_format_attribute_implicit_this_format_string) 1713 << IdxExpr->getSourceRange(); 1714 return; 1715 } 1716 ArgIdx--; 1717 } 1718 1719 // make sure the format string is really a string 1720 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1721 1722 if (Kind == CFStringFormat) { 1723 if (!isCFStringType(Ty, S.Context)) { 1724 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1725 << "a CFString" << IdxExpr->getSourceRange(); 1726 return; 1727 } 1728 } else if (Kind == NSStringFormat) { 1729 // FIXME: do we need to check if the type is NSString*? What are the 1730 // semantics? 1731 if (!isNSStringType(Ty, S.Context)) { 1732 // FIXME: Should highlight the actual expression that has the wrong type. 1733 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1734 << "an NSString" << IdxExpr->getSourceRange(); 1735 return; 1736 } 1737 } else if (!Ty->isPointerType() || 1738 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1739 // FIXME: Should highlight the actual expression that has the wrong type. 1740 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1741 << "a string type" << IdxExpr->getSourceRange(); 1742 return; 1743 } 1744 1745 // check the 3rd argument 1746 Expr *FirstArgExpr = Attr.getArg(1); 1747 llvm::APSInt FirstArg(32); 1748 if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 1749 !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1750 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1751 << "format" << 3 << FirstArgExpr->getSourceRange(); 1752 return; 1753 } 1754 1755 // check if the function is variadic if the 3rd argument non-zero 1756 if (FirstArg != 0) { 1757 if (isFunctionOrMethodVariadic(d)) { 1758 ++NumArgs; // +1 for ... 1759 } else { 1760 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1761 return; 1762 } 1763 } 1764 1765 // strftime requires FirstArg to be 0 because it doesn't read from any 1766 // variable the input is just the current time + the format string. 1767 if (Kind == StrftimeFormat) { 1768 if (FirstArg != 0) { 1769 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1770 << FirstArgExpr->getSourceRange(); 1771 return; 1772 } 1773 // if 0 it disables parameter checking (to use with e.g. va_list) 1774 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1775 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1776 << "format" << 3 << FirstArgExpr->getSourceRange(); 1777 return; 1778 } 1779 1780 d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format, 1781 Idx.getZExtValue(), 1782 FirstArg.getZExtValue())); 1783} 1784 1785static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1786 Sema &S) { 1787 // check the attribute arguments. 1788 if (Attr.getNumArgs() != 0) { 1789 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1790 return; 1791 } 1792 1793 // Try to find the underlying union declaration. 1794 RecordDecl *RD = 0; 1795 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1796 if (TD && TD->getUnderlyingType()->isUnionType()) 1797 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1798 else 1799 RD = dyn_cast<RecordDecl>(d); 1800 1801 if (!RD || !RD->isUnion()) { 1802 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1803 << Attr.getName() << 1 /*union*/; 1804 return; 1805 } 1806 1807 if (!RD->isDefinition()) { 1808 S.Diag(Attr.getLoc(), 1809 diag::warn_transparent_union_attribute_not_definition); 1810 return; 1811 } 1812 1813 RecordDecl::field_iterator Field = RD->field_begin(), 1814 FieldEnd = RD->field_end(); 1815 if (Field == FieldEnd) { 1816 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1817 return; 1818 } 1819 1820 FieldDecl *FirstField = *Field; 1821 QualType FirstType = FirstField->getType(); 1822 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 1823 S.Diag(FirstField->getLocation(), 1824 diag::warn_transparent_union_attribute_floating) 1825 << FirstType->isVectorType() << FirstType; 1826 return; 1827 } 1828 1829 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1830 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1831 for (; Field != FieldEnd; ++Field) { 1832 QualType FieldType = Field->getType(); 1833 if (S.Context.getTypeSize(FieldType) != FirstSize || 1834 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1835 // Warn if we drop the attribute. 1836 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1837 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1838 : S.Context.getTypeAlign(FieldType); 1839 S.Diag(Field->getLocation(), 1840 diag::warn_transparent_union_attribute_field_size_align) 1841 << isSize << Field->getDeclName() << FieldBits; 1842 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1843 S.Diag(FirstField->getLocation(), 1844 diag::note_transparent_union_first_field_size_align) 1845 << isSize << FirstBits; 1846 return; 1847 } 1848 } 1849 1850 RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context)); 1851} 1852 1853static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1854 // check the attribute arguments. 1855 if (Attr.getNumArgs() != 1) { 1856 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1857 return; 1858 } 1859 Expr *ArgExpr = Attr.getArg(0); 1860 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1861 1862 // Make sure that there is a string literal as the annotation's single 1863 // argument. 1864 if (!SE) { 1865 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 1866 return; 1867 } 1868 d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, 1869 SE->getString())); 1870} 1871 1872static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1873 // check the attribute arguments. 1874 if (Attr.getNumArgs() > 1) { 1875 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1876 return; 1877 } 1878 1879 //FIXME: The C++0x version of this attribute has more limited applicabilty 1880 // than GNU's, and should error out when it is used to specify a 1881 // weaker alignment, rather than being silently ignored. 1882 1883 if (Attr.getNumArgs() == 0) { 1884 D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0)); 1885 return; 1886 } 1887 1888 S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0)); 1889} 1890 1891void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { 1892 if (E->isTypeDependent() || E->isValueDependent()) { 1893 // Save dependent expressions in the AST to be instantiated. 1894 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 1895 return; 1896 } 1897 1898 // FIXME: Cache the number on the Attr object? 1899 llvm::APSInt Alignment(32); 1900 if (!E->isIntegerConstantExpr(Alignment, Context)) { 1901 Diag(AttrLoc, diag::err_attribute_argument_not_int) 1902 << "aligned" << E->getSourceRange(); 1903 return; 1904 } 1905 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1906 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 1907 << E->getSourceRange(); 1908 return; 1909 } 1910 1911 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 1912} 1913 1914void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) { 1915 // FIXME: Cache the number on the Attr object if non-dependent? 1916 // FIXME: Perform checking of type validity 1917 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS)); 1918 return; 1919} 1920 1921/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1922/// type. 1923/// 1924/// Despite what would be logical, the mode attribute is a decl attribute, not a 1925/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1926/// HImode, not an intermediate pointer. 1927static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1928 // This attribute isn't documented, but glibc uses it. It changes 1929 // the width of an int or unsigned int to the specified size. 1930 1931 // Check that there aren't any arguments 1932 if (Attr.getNumArgs() != 0) { 1933 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1934 return; 1935 } 1936 1937 IdentifierInfo *Name = Attr.getParameterName(); 1938 if (!Name) { 1939 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1940 return; 1941 } 1942 1943 llvm::StringRef Str = Attr.getParameterName()->getName(); 1944 1945 // Normalize the attribute name, __foo__ becomes foo. 1946 if (Str.startswith("__") && Str.endswith("__")) 1947 Str = Str.substr(2, Str.size() - 4); 1948 1949 unsigned DestWidth = 0; 1950 bool IntegerMode = true; 1951 bool ComplexMode = false; 1952 switch (Str.size()) { 1953 case 2: 1954 switch (Str[0]) { 1955 case 'Q': DestWidth = 8; break; 1956 case 'H': DestWidth = 16; break; 1957 case 'S': DestWidth = 32; break; 1958 case 'D': DestWidth = 64; break; 1959 case 'X': DestWidth = 96; break; 1960 case 'T': DestWidth = 128; break; 1961 } 1962 if (Str[1] == 'F') { 1963 IntegerMode = false; 1964 } else if (Str[1] == 'C') { 1965 IntegerMode = false; 1966 ComplexMode = true; 1967 } else if (Str[1] != 'I') { 1968 DestWidth = 0; 1969 } 1970 break; 1971 case 4: 1972 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1973 // pointer on PIC16 and other embedded platforms. 1974 if (Str == "word") 1975 DestWidth = S.Context.Target.getPointerWidth(0); 1976 else if (Str == "byte") 1977 DestWidth = S.Context.Target.getCharWidth(); 1978 break; 1979 case 7: 1980 if (Str == "pointer") 1981 DestWidth = S.Context.Target.getPointerWidth(0); 1982 break; 1983 } 1984 1985 QualType OldTy; 1986 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1987 OldTy = TD->getUnderlyingType(); 1988 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1989 OldTy = VD->getType(); 1990 else { 1991 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1992 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1993 return; 1994 } 1995 1996 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 1997 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1998 else if (IntegerMode) { 1999 if (!OldTy->isIntegralOrEnumerationType()) 2000 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 2001 } else if (ComplexMode) { 2002 if (!OldTy->isComplexType()) 2003 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 2004 } else { 2005 if (!OldTy->isFloatingType()) 2006 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 2007 } 2008 2009 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 2010 // and friends, at least with glibc. 2011 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 2012 // width on unusual platforms. 2013 // FIXME: Make sure floating-point mappings are accurate 2014 // FIXME: Support XF and TF types 2015 QualType NewTy; 2016 switch (DestWidth) { 2017 case 0: 2018 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 2019 return; 2020 default: 2021 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2022 return; 2023 case 8: 2024 if (!IntegerMode) { 2025 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2026 return; 2027 } 2028 if (OldTy->isSignedIntegerType()) 2029 NewTy = S.Context.SignedCharTy; 2030 else 2031 NewTy = S.Context.UnsignedCharTy; 2032 break; 2033 case 16: 2034 if (!IntegerMode) { 2035 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2036 return; 2037 } 2038 if (OldTy->isSignedIntegerType()) 2039 NewTy = S.Context.ShortTy; 2040 else 2041 NewTy = S.Context.UnsignedShortTy; 2042 break; 2043 case 32: 2044 if (!IntegerMode) 2045 NewTy = S.Context.FloatTy; 2046 else if (OldTy->isSignedIntegerType()) 2047 NewTy = S.Context.IntTy; 2048 else 2049 NewTy = S.Context.UnsignedIntTy; 2050 break; 2051 case 64: 2052 if (!IntegerMode) 2053 NewTy = S.Context.DoubleTy; 2054 else if (OldTy->isSignedIntegerType()) 2055 if (S.Context.Target.getLongWidth() == 64) 2056 NewTy = S.Context.LongTy; 2057 else 2058 NewTy = S.Context.LongLongTy; 2059 else 2060 if (S.Context.Target.getLongWidth() == 64) 2061 NewTy = S.Context.UnsignedLongTy; 2062 else 2063 NewTy = S.Context.UnsignedLongLongTy; 2064 break; 2065 case 96: 2066 NewTy = S.Context.LongDoubleTy; 2067 break; 2068 case 128: 2069 if (!IntegerMode) { 2070 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2071 return; 2072 } 2073 if (OldTy->isSignedIntegerType()) 2074 NewTy = S.Context.Int128Ty; 2075 else 2076 NewTy = S.Context.UnsignedInt128Ty; 2077 break; 2078 } 2079 2080 if (ComplexMode) { 2081 NewTy = S.Context.getComplexType(NewTy); 2082 } 2083 2084 // Install the new type. 2085 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 2086 // FIXME: preserve existing source info. 2087 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 2088 } else 2089 cast<ValueDecl>(D)->setType(NewTy); 2090} 2091 2092static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2093 // check the attribute arguments. 2094 if (Attr.getNumArgs() > 0) { 2095 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2096 return; 2097 } 2098 2099 if (!isFunctionOrMethod(d)) { 2100 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2101 << Attr.getName() << 0 /*function*/; 2102 return; 2103 } 2104 2105 d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context)); 2106} 2107 2108static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2109 // check the attribute arguments. 2110 if (Attr.getNumArgs() != 0) { 2111 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2112 return; 2113 } 2114 2115 if (!isa<FunctionDecl>(d)) { 2116 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2117 << Attr.getName() << 0 /*function*/; 2118 return; 2119 } 2120 2121 d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context)); 2122} 2123 2124static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr, 2125 Sema &S) { 2126 // check the attribute arguments. 2127 if (Attr.getNumArgs() != 0) { 2128 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2129 return; 2130 } 2131 2132 if (!isa<FunctionDecl>(d)) { 2133 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2134 << Attr.getName() << 0 /*function*/; 2135 return; 2136 } 2137 2138 d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), 2139 S.Context)); 2140} 2141 2142static void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2143 if (S.LangOpts.CUDA) { 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<VarDecl>(d)) { 2151 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2152 << Attr.getName() << 12 /*variable*/; 2153 return; 2154 } 2155 2156 d->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context)); 2157 } else { 2158 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 2159 } 2160} 2161 2162static void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2163 if (S.LangOpts.CUDA) { 2164 // check the attribute arguments. 2165 if (Attr.getNumArgs() != 0) { 2166 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2167 return; 2168 } 2169 2170 if (!isa<FunctionDecl>(d) && !isa<VarDecl>(d)) { 2171 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2172 << Attr.getName() << 2 /*variable and function*/; 2173 return; 2174 } 2175 2176 d->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context)); 2177 } else { 2178 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 2179 } 2180} 2181 2182static void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2183 if (S.LangOpts.CUDA) { 2184 // check the attribute arguments. 2185 if (Attr.getNumArgs() != 0) { 2186 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2187 return; 2188 } 2189 2190 if (!isa<FunctionDecl>(d)) { 2191 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2192 << Attr.getName() << 0 /*function*/; 2193 return; 2194 } 2195 2196 FunctionDecl *FD = cast<FunctionDecl>(d); 2197 if (!FD->getResultType()->isVoidType()) { 2198 TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 2199 if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 2200 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 2201 << FD->getType() 2202 << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 2203 "void"); 2204 } else { 2205 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 2206 << FD->getType(); 2207 } 2208 return; 2209 } 2210 2211 d->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context)); 2212 } else { 2213 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 2214 } 2215} 2216 2217static void HandleHostAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2218 if (S.LangOpts.CUDA) { 2219 // check the attribute arguments. 2220 if (Attr.getNumArgs() != 0) { 2221 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2222 return; 2223 } 2224 2225 if (!isa<FunctionDecl>(d)) { 2226 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2227 << Attr.getName() << 0 /*function*/; 2228 return; 2229 } 2230 2231 d->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context)); 2232 } else { 2233 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 2234 } 2235} 2236 2237static void HandleSharedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2238 if (S.LangOpts.CUDA) { 2239 // check the attribute arguments. 2240 if (Attr.getNumArgs() != 0) { 2241 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2242 return; 2243 } 2244 2245 if (!isa<VarDecl>(d)) { 2246 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2247 << Attr.getName() << 12 /*variable*/; 2248 return; 2249 } 2250 2251 d->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context)); 2252 } else { 2253 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 2254 } 2255} 2256 2257static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2258 // check the attribute arguments. 2259 if (Attr.getNumArgs() != 0) { 2260 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2261 return; 2262 } 2263 2264 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 2265 if (Fn == 0) { 2266 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2267 << Attr.getName() << 0 /*function*/; 2268 return; 2269 } 2270 2271 if (!Fn->isInlineSpecified()) { 2272 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 2273 return; 2274 } 2275 2276 d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context)); 2277} 2278 2279static void HandleCallConvAttr(Decl *d, const AttributeList &attr, Sema &S) { 2280 if (hasDeclarator(d)) return; 2281 2282 // Diagnostic is emitted elsewhere: here we store the (valid) attr 2283 // in the Decl node for syntactic reasoning, e.g., pretty-printing. 2284 CallingConv CC; 2285 if (S.CheckCallingConvAttr(attr, CC)) 2286 return; 2287 2288 if (!isa<ObjCMethodDecl>(d)) { 2289 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2290 << attr.getName() << 0 /*function*/; 2291 return; 2292 } 2293 2294 switch (attr.getKind()) { 2295 case AttributeList::AT_fastcall: 2296 d->addAttr(::new (S.Context) FastCallAttr(attr.getLoc(), S.Context)); 2297 return; 2298 case AttributeList::AT_stdcall: 2299 d->addAttr(::new (S.Context) StdCallAttr(attr.getLoc(), S.Context)); 2300 return; 2301 case AttributeList::AT_thiscall: 2302 d->addAttr(::new (S.Context) ThisCallAttr(attr.getLoc(), S.Context)); 2303 return; 2304 case AttributeList::AT_cdecl: 2305 d->addAttr(::new (S.Context) CDeclAttr(attr.getLoc(), S.Context)); 2306 return; 2307 case AttributeList::AT_pascal: 2308 d->addAttr(::new (S.Context) PascalAttr(attr.getLoc(), S.Context)); 2309 return; 2310 default: 2311 llvm_unreachable("unexpected attribute kind"); 2312 return; 2313 } 2314} 2315 2316bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 2317 if (attr.isInvalid()) 2318 return true; 2319 2320 if (attr.getNumArgs() != 0) { 2321 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2322 attr.setInvalid(); 2323 return true; 2324 } 2325 2326 // TODO: diagnose uses of these conventions on the wrong target. 2327 switch (attr.getKind()) { 2328 case AttributeList::AT_cdecl: CC = CC_C; break; 2329 case AttributeList::AT_fastcall: CC = CC_X86FastCall; break; 2330 case AttributeList::AT_stdcall: CC = CC_X86StdCall; break; 2331 case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break; 2332 case AttributeList::AT_pascal: CC = CC_X86Pascal; break; 2333 default: llvm_unreachable("unexpected attribute kind"); return true; 2334 } 2335 2336 return false; 2337} 2338 2339static void HandleRegparmAttr(Decl *d, const AttributeList &attr, Sema &S) { 2340 if (hasDeclarator(d)) return; 2341 2342 unsigned numParams; 2343 if (S.CheckRegparmAttr(attr, numParams)) 2344 return; 2345 2346 if (!isa<ObjCMethodDecl>(d)) { 2347 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2348 << attr.getName() << 0 /*function*/; 2349 return; 2350 } 2351 2352 d->addAttr(::new (S.Context) RegparmAttr(attr.getLoc(), S.Context, numParams)); 2353} 2354 2355/// Checks a regparm attribute, returning true if it is ill-formed and 2356/// otherwise setting numParams to the appropriate value. 2357bool Sema::CheckRegparmAttr(const AttributeList &attr, unsigned &numParams) { 2358 if (attr.isInvalid()) 2359 return true; 2360 2361 if (attr.getNumArgs() != 1) { 2362 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2363 attr.setInvalid(); 2364 return true; 2365 } 2366 2367 Expr *NumParamsExpr = attr.getArg(0); 2368 llvm::APSInt NumParams(32); 2369 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 2370 !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 2371 Diag(attr.getLoc(), diag::err_attribute_argument_not_int) 2372 << "regparm" << NumParamsExpr->getSourceRange(); 2373 attr.setInvalid(); 2374 return true; 2375 } 2376 2377 if (Context.Target.getRegParmMax() == 0) { 2378 Diag(attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 2379 << NumParamsExpr->getSourceRange(); 2380 attr.setInvalid(); 2381 return true; 2382 } 2383 2384 numParams = NumParams.getZExtValue(); 2385 if (numParams > Context.Target.getRegParmMax()) { 2386 Diag(attr.getLoc(), diag::err_attribute_regparm_invalid_number) 2387 << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 2388 attr.setInvalid(); 2389 return true; 2390 } 2391 2392 return false; 2393} 2394 2395static void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){ 2396 if (S.LangOpts.CUDA) { 2397 // check the attribute arguments. 2398 if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 2399 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 2400 << "1 or 2"; 2401 return; 2402 } 2403 2404 if (!isFunctionOrMethod(d)) { 2405 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2406 << Attr.getName() << 0 /*function*/; 2407 return; 2408 } 2409 2410 Expr *MaxThreadsExpr = Attr.getArg(0); 2411 llvm::APSInt MaxThreads(32); 2412 if (MaxThreadsExpr->isTypeDependent() || 2413 MaxThreadsExpr->isValueDependent() || 2414 !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 2415 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 2416 << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 2417 return; 2418 } 2419 2420 llvm::APSInt MinBlocks(32); 2421 if (Attr.getNumArgs() > 1) { 2422 Expr *MinBlocksExpr = Attr.getArg(1); 2423 if (MinBlocksExpr->isTypeDependent() || 2424 MinBlocksExpr->isValueDependent() || 2425 !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 2426 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 2427 << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 2428 return; 2429 } 2430 } 2431 2432 d->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context, 2433 MaxThreads.getZExtValue(), 2434 MinBlocks.getZExtValue())); 2435 } else { 2436 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 2437 } 2438} 2439 2440//===----------------------------------------------------------------------===// 2441// Checker-specific attribute handlers. 2442//===----------------------------------------------------------------------===// 2443 2444static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 2445 Sema &S) { 2446 2447 QualType RetTy; 2448 2449 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 2450 RetTy = MD->getResultType(); 2451 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 2452 RetTy = FD->getResultType(); 2453 else { 2454 SourceLocation L = Attr.getLoc(); 2455 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 2456 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 2457 return; 2458 } 2459 2460 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 2461 || RetTy->getAs<ObjCObjectPointerType>())) { 2462 SourceLocation L = Attr.getLoc(); 2463 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 2464 << SourceRange(L, L) << Attr.getName(); 2465 return; 2466 } 2467 2468 switch (Attr.getKind()) { 2469 default: 2470 assert(0 && "invalid ownership attribute"); 2471 return; 2472 case AttributeList::AT_cf_returns_not_retained: 2473 d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), 2474 S.Context)); 2475 return; 2476 case AttributeList::AT_ns_returns_not_retained: 2477 d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), 2478 S.Context)); 2479 return; 2480 case AttributeList::AT_cf_returns_retained: 2481 d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), 2482 S.Context)); 2483 return; 2484 case AttributeList::AT_ns_returns_retained: 2485 d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), 2486 S.Context)); 2487 return; 2488 }; 2489} 2490 2491static bool isKnownDeclSpecAttr(const AttributeList &Attr) { 2492 return Attr.getKind() == AttributeList::AT_dllimport || 2493 Attr.getKind() == AttributeList::AT_dllexport || 2494 Attr.getKind() == AttributeList::AT_uuid; 2495} 2496 2497//===----------------------------------------------------------------------===// 2498// Microsoft specific attribute handlers. 2499//===----------------------------------------------------------------------===// 2500 2501static void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2502 if (S.LangOpts.Microsoft || S.LangOpts.Borland) { 2503 // check the attribute arguments. 2504 if (Attr.getNumArgs() != 1) { 2505 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2506 return; 2507 } 2508 Expr *Arg = Attr.getArg(0); 2509 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 2510 if (Str == 0 || Str->isWide()) { 2511 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 2512 << "uuid" << 1; 2513 return; 2514 } 2515 2516 llvm::StringRef StrRef = Str->getString(); 2517 2518 bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 2519 StrRef.back() == '}'; 2520 2521 // Validate GUID length. 2522 if (IsCurly && StrRef.size() != 38) { 2523 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2524 return; 2525 } 2526 if (!IsCurly && StrRef.size() != 36) { 2527 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2528 return; 2529 } 2530 2531 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 2532 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 2533 llvm::StringRef::iterator I = StrRef.begin(); 2534 if (IsCurly) // Skip the optional '{' 2535 ++I; 2536 2537 for (int i = 0; i < 36; ++i) { 2538 if (i == 8 || i == 13 || i == 18 || i == 23) { 2539 if (*I != '-') { 2540 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2541 return; 2542 } 2543 } else if (!isxdigit(*I)) { 2544 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2545 return; 2546 } 2547 I++; 2548 } 2549 2550 d->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context, 2551 Str->getString())); 2552 } else 2553 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 2554} 2555 2556//===----------------------------------------------------------------------===// 2557// Top Level Sema Entry Points 2558//===----------------------------------------------------------------------===// 2559 2560static void ProcessNonInheritableDeclAttr(Scope *scope, Decl *D, 2561 const AttributeList &Attr, Sema &S) { 2562 switch (Attr.getKind()) { 2563 case AttributeList::AT_device: HandleDeviceAttr (D, Attr, S); break; 2564 case AttributeList::AT_host: HandleHostAttr (D, Attr, S); break; 2565 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 2566 default: 2567 break; 2568 } 2569} 2570 2571static void ProcessInheritableDeclAttr(Scope *scope, Decl *D, 2572 const AttributeList &Attr, Sema &S) { 2573 switch (Attr.getKind()) { 2574 case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 2575 case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 2576 case AttributeList::AT_IBOutletCollection: 2577 HandleIBOutletCollection(D, Attr, S); break; 2578 case AttributeList::AT_address_space: 2579 case AttributeList::AT_objc_gc: 2580 case AttributeList::AT_vector_size: 2581 case AttributeList::AT_neon_vector_type: 2582 case AttributeList::AT_neon_polyvector_type: 2583 // Ignore these, these are type attributes, handled by 2584 // ProcessTypeAttributes. 2585 break; 2586 case AttributeList::AT_device: 2587 case AttributeList::AT_host: 2588 case AttributeList::AT_overloadable: 2589 // Ignore, this is a non-inheritable attribute, handled 2590 // by ProcessNonInheritableDeclAttr. 2591 break; 2592 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 2593 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 2594 case AttributeList::AT_always_inline: 2595 HandleAlwaysInlineAttr (D, Attr, S); break; 2596 case AttributeList::AT_analyzer_noreturn: 2597 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 2598 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 2599 case AttributeList::AT_carries_dependency: 2600 HandleDependencyAttr (D, Attr, S); break; 2601 case AttributeList::AT_common: HandleCommonAttr (D, Attr, S); break; 2602 case AttributeList::AT_constant: HandleConstantAttr (D, Attr, S); break; 2603 case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 2604 case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 2605 case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 2606 case AttributeList::AT_ext_vector_type: 2607 HandleExtVectorTypeAttr(scope, D, Attr, S); 2608 break; 2609 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 2610 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 2611 case AttributeList::AT_global: HandleGlobalAttr (D, Attr, S); break; 2612 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 2613 case AttributeList::AT_launch_bounds: 2614 HandleLaunchBoundsAttr(D, Attr, S); 2615 break; 2616 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 2617 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 2618 case AttributeList::AT_may_alias: HandleMayAliasAttr (D, Attr, S); break; 2619 case AttributeList::AT_nocommon: HandleNoCommonAttr (D, Attr, S); break; 2620 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 2621 case AttributeList::AT_ownership_returns: 2622 case AttributeList::AT_ownership_takes: 2623 case AttributeList::AT_ownership_holds: 2624 HandleOwnershipAttr (D, Attr, S); break; 2625 case AttributeList::AT_naked: HandleNakedAttr (D, Attr, S); break; 2626 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 2627 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 2628 case AttributeList::AT_shared: HandleSharedAttr (D, Attr, S); break; 2629 case AttributeList::AT_vecreturn: HandleVecReturnAttr (D, Attr, S); break; 2630 2631 // Checker-specific. 2632 case AttributeList::AT_ns_returns_not_retained: 2633 case AttributeList::AT_cf_returns_not_retained: 2634 case AttributeList::AT_ns_returns_retained: 2635 case AttributeList::AT_cf_returns_retained: 2636 HandleNSReturnsRetainedAttr(D, Attr, S); break; 2637 2638 case AttributeList::AT_reqd_wg_size: 2639 HandleReqdWorkGroupSize(D, Attr, S); break; 2640 2641 case AttributeList::AT_init_priority: 2642 HandleInitPriorityAttr(D, Attr, S); break; 2643 2644 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 2645 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 2646 case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 2647 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 2648 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 2649 case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 2650 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 2651 break; 2652 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 2653 case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 2654 case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 2655 case AttributeList::AT_transparent_union: 2656 HandleTransparentUnionAttr(D, Attr, S); 2657 break; 2658 case AttributeList::AT_objc_exception: 2659 HandleObjCExceptionAttr(D, Attr, S); 2660 break; 2661 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 2662 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 2663 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 2664 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 2665 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 2666 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 2667 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 2668 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 2669 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 2670 case AttributeList::IgnoredAttribute: 2671 // Just ignore 2672 break; 2673 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 2674 HandleNoInstrumentFunctionAttr(D, Attr, S); 2675 break; 2676 case AttributeList::AT_stdcall: 2677 case AttributeList::AT_cdecl: 2678 case AttributeList::AT_fastcall: 2679 case AttributeList::AT_thiscall: 2680 case AttributeList::AT_pascal: 2681 HandleCallConvAttr(D, Attr, S); 2682 break; 2683 case AttributeList::AT_uuid: 2684 HandleUuidAttr(D, Attr, S); 2685 break; 2686 default: 2687 // Ask target about the attribute. 2688 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 2689 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 2690 S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 2691 << Attr.getName(); 2692 break; 2693 } 2694} 2695 2696/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 2697/// the attribute applies to decls. If the attribute is a type attribute, just 2698/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 2699/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 2700static void ProcessDeclAttribute(Scope *scope, Decl *D, 2701 const AttributeList &Attr, Sema &S, 2702 bool NonInheritable, bool Inheritable) { 2703 if (Attr.isInvalid()) 2704 return; 2705 2706 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 2707 // FIXME: Try to deal with other __declspec attributes! 2708 return; 2709 2710 if (NonInheritable) 2711 ProcessNonInheritableDeclAttr(scope, D, Attr, S); 2712 2713 if (Inheritable) 2714 ProcessInheritableDeclAttr(scope, D, Attr, S); 2715} 2716 2717/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 2718/// attribute list to the specified decl, ignoring any type attributes. 2719void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 2720 const AttributeList *AttrList, 2721 bool NonInheritable, bool Inheritable) { 2722 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 2723 ProcessDeclAttribute(S, D, *l, *this, NonInheritable, Inheritable); 2724 } 2725 2726 // GCC accepts 2727 // static int a9 __attribute__((weakref)); 2728 // but that looks really pointless. We reject it. 2729 if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 2730 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 2731 dyn_cast<NamedDecl>(D)->getNameAsString(); 2732 return; 2733 } 2734} 2735 2736/// DeclClonePragmaWeak - clone existing decl (maybe definition), 2737/// #pragma weak needs a non-definition decl and source may not have one 2738NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 2739 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 2740 NamedDecl *NewD = 0; 2741 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 2742 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 2743 FD->getLocation(), DeclarationName(II), 2744 FD->getType(), FD->getTypeSourceInfo()); 2745 if (FD->getQualifier()) { 2746 FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 2747 NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 2748 } 2749 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 2750 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 2751 VD->getLocation(), II, 2752 VD->getType(), VD->getTypeSourceInfo(), 2753 VD->getStorageClass(), 2754 VD->getStorageClassAsWritten()); 2755 if (VD->getQualifier()) { 2756 VarDecl *NewVD = cast<VarDecl>(NewD); 2757 NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 2758 } 2759 } 2760 return NewD; 2761} 2762 2763/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 2764/// applied to it, possibly with an alias. 2765void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 2766 if (W.getUsed()) return; // only do this once 2767 W.setUsed(true); 2768 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 2769 IdentifierInfo *NDId = ND->getIdentifier(); 2770 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 2771 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 2772 NDId->getName())); 2773 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2774 WeakTopLevelDecl.push_back(NewD); 2775 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 2776 // to insert Decl at TU scope, sorry. 2777 DeclContext *SavedContext = CurContext; 2778 CurContext = Context.getTranslationUnitDecl(); 2779 PushOnScopeChains(NewD, S); 2780 CurContext = SavedContext; 2781 } else { // just add weak to existing 2782 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2783 } 2784} 2785 2786/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 2787/// it, apply them to D. This is a bit tricky because PD can have attributes 2788/// specified in many different places, and we need to find and apply them all. 2789void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 2790 bool NonInheritable, bool Inheritable) { 2791 // It's valid to "forward-declare" #pragma weak, in which case we 2792 // have to do this. 2793 if (Inheritable && !WeakUndeclaredIdentifiers.empty()) { 2794 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 2795 if (IdentifierInfo *Id = ND->getIdentifier()) { 2796 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 2797 = WeakUndeclaredIdentifiers.find(Id); 2798 if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 2799 WeakInfo W = I->second; 2800 DeclApplyPragmaWeak(S, ND, W); 2801 WeakUndeclaredIdentifiers[Id] = W; 2802 } 2803 } 2804 } 2805 } 2806 2807 // Apply decl attributes from the DeclSpec if present. 2808 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 2809 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 2810 2811 // Walk the declarator structure, applying decl attributes that were in a type 2812 // position to the decl itself. This handles cases like: 2813 // int *__attr__(x)** D; 2814 // when X is a decl attribute. 2815 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 2816 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 2817 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 2818 2819 // Finally, apply any attributes on the decl itself. 2820 if (const AttributeList *Attrs = PD.getAttributes()) 2821 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 2822} 2823 2824/// PushParsingDeclaration - Enter a new "scope" of deprecation 2825/// warnings. 2826/// 2827/// The state token we use is the start index of this scope 2828/// on the warning stack. 2829Sema::ParsingDeclStackState Sema::PushParsingDeclaration() { 2830 ParsingDeclDepth++; 2831 return (ParsingDeclStackState) DelayedDiagnostics.size(); 2832} 2833 2834void Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) { 2835 assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 2836 ParsingDeclDepth--; 2837 2838 if (DelayedDiagnostics.empty()) 2839 return; 2840 2841 unsigned SavedIndex = (unsigned) S; 2842 assert(SavedIndex <= DelayedDiagnostics.size() && 2843 "saved index is out of bounds"); 2844 2845 unsigned E = DelayedDiagnostics.size(); 2846 2847 // We only want to actually emit delayed diagnostics when we 2848 // successfully parsed a decl. 2849 if (D) { 2850 // We really do want to start with 0 here. We get one push for a 2851 // decl spec and another for each declarator; in a decl group like: 2852 // deprecated_typedef foo, *bar, baz(); 2853 // only the declarator pops will be passed decls. This is correct; 2854 // we really do need to consider delayed diagnostics from the decl spec 2855 // for each of the different declarations. 2856 for (unsigned I = 0; I != E; ++I) { 2857 if (DelayedDiagnostics[I].Triggered) 2858 continue; 2859 2860 switch (DelayedDiagnostics[I].Kind) { 2861 case DelayedDiagnostic::Deprecation: 2862 HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 2863 break; 2864 2865 case DelayedDiagnostic::Access: 2866 HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 2867 break; 2868 } 2869 } 2870 } 2871 2872 // Destroy all the delayed diagnostics we're about to pop off. 2873 for (unsigned I = SavedIndex; I != E; ++I) 2874 DelayedDiagnostics[I].destroy(); 2875 2876 DelayedDiagnostics.set_size(SavedIndex); 2877} 2878 2879static bool isDeclDeprecated(Decl *D) { 2880 do { 2881 if (D->hasAttr<DeprecatedAttr>()) 2882 return true; 2883 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 2884 return false; 2885} 2886 2887void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 2888 Decl *Ctx) { 2889 if (isDeclDeprecated(Ctx)) 2890 return; 2891 2892 DD.Triggered = true; 2893 if (!DD.getDeprecationMessage().empty()) 2894 Diag(DD.Loc, diag::warn_deprecated_message) 2895 << DD.getDeprecationDecl()->getDeclName() 2896 << DD.getDeprecationMessage(); 2897 else 2898 Diag(DD.Loc, diag::warn_deprecated) 2899 << DD.getDeprecationDecl()->getDeclName(); 2900} 2901 2902void Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message, 2903 SourceLocation Loc, 2904 bool UnknownObjCClass) { 2905 // Delay if we're currently parsing a declaration. 2906 if (ParsingDeclDepth) { 2907 DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D, 2908 Message)); 2909 return; 2910 } 2911 2912 // Otherwise, don't warn if our current context is deprecated. 2913 if (isDeclDeprecated(cast<Decl>(CurContext))) 2914 return; 2915 if (!Message.empty()) 2916 Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 2917 << Message; 2918 else { 2919 if (!UnknownObjCClass) 2920 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 2921 else 2922 Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName(); 2923 } 2924} 2925