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