SemaDeclAttr.cpp revision 5dc53c9c2328b5bea5422005b04960c18afd83ad
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 "Sema.h" 15#include "clang/AST/ASTContext.h" 16#include "clang/AST/DeclObjC.h" 17#include "clang/AST/Expr.h" 18#include "clang/Basic/TargetInfo.h" 19#include "clang/Parse/DeclSpec.h" 20#include <llvm/ADT/StringExtras.h> 21using namespace clang; 22 23//===----------------------------------------------------------------------===// 24// Helper functions 25//===----------------------------------------------------------------------===// 26 27static const FunctionType *getFunctionType(Decl *d) { 28 QualType Ty; 29 if (ValueDecl *decl = dyn_cast<ValueDecl>(d)) 30 Ty = decl->getType(); 31 else if (FieldDecl *decl = dyn_cast<FieldDecl>(d)) 32 Ty = decl->getType(); 33 else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 34 Ty = decl->getUnderlyingType(); 35 else 36 return 0; 37 38 if (Ty->isFunctionPointerType()) 39 Ty = Ty->getAsPointerType()->getPointeeType(); 40 41 return Ty->getAsFunctionType(); 42} 43 44// FIXME: We should provide an abstraction around a method or function 45// to provide the following bits of information. 46 47/// isFunctionOrMethod - Return true if the given decl has function 48/// type (function or function-typed variable) or an Objective-C 49/// method. 50static bool isFunctionOrMethod(Decl *d) { 51 return getFunctionType(d) || isa<ObjCMethodDecl>(d); 52} 53 54/// hasFunctionProto - Return true if the given decl has a argument 55/// information. This decl should have already passed 56/// isFunctionOrMethod. 57static bool hasFunctionProto(Decl *d) { 58 if (const FunctionType *FnTy = getFunctionType(d)) { 59 return isa<FunctionProtoType>(FnTy); 60 } else { 61 assert(isa<ObjCMethodDecl>(d)); 62 return true; 63 } 64} 65 66/// getFunctionOrMethodNumArgs - Return number of function or method 67/// arguments. It is an error to call this on a K&R function (use 68/// hasFunctionProto first). 69static unsigned getFunctionOrMethodNumArgs(Decl *d) { 70 if (const FunctionType *FnTy = getFunctionType(d)) 71 return cast<FunctionProtoType>(FnTy)->getNumArgs(); 72 return cast<ObjCMethodDecl>(d)->param_size(); 73} 74 75static QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) { 76 if (const FunctionType *FnTy = getFunctionType(d)) 77 return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 78 79 return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 80} 81 82static bool isFunctionOrMethodVariadic(Decl *d) { 83 if (const FunctionType *FnTy = getFunctionType(d)) { 84 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 85 return proto->isVariadic(); 86 } else { 87 return cast<ObjCMethodDecl>(d)->isVariadic(); 88 } 89} 90 91static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 92 const PointerType *PT = T->getAsPointerType(); 93 if (!PT) 94 return false; 95 96 const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType(); 97 if (!ClsT) 98 return false; 99 100 IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 101 102 // FIXME: Should we walk the chain of classes? 103 return ClsName == &Ctx.Idents.get("NSString") || 104 ClsName == &Ctx.Idents.get("NSMutableString"); 105} 106 107static inline bool isCFStringType(QualType T, ASTContext &Ctx) { 108 const PointerType *PT = T->getAsPointerType(); 109 if (!PT) 110 return false; 111 112 const RecordType *RT = PT->getPointeeType()->getAsRecordType(); 113 if (!RT) 114 return false; 115 116 const RecordDecl *RD = RT->getDecl(); 117 if (RD->getTagKind() != TagDecl::TK_struct) 118 return false; 119 120 return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 121} 122 123//===----------------------------------------------------------------------===// 124// Attribute Implementations 125//===----------------------------------------------------------------------===// 126 127// FIXME: All this manual attribute parsing code is gross. At the 128// least add some helper functions to check most argument patterns (# 129// and types of args). 130 131static void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr, 132 Sema &S) { 133 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 134 if (tDecl == 0) { 135 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 136 return; 137 } 138 139 QualType curType = tDecl->getUnderlyingType(); 140 // check the attribute arguments. 141 if (Attr.getNumArgs() != 1) { 142 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 143 return; 144 } 145 Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 146 llvm::APSInt vecSize(32); 147 if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 148 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 149 << "ext_vector_type" << sizeExpr->getSourceRange(); 150 return; 151 } 152 // unlike gcc's vector_size attribute, we do not allow vectors to be defined 153 // in conjunction with complex types (pointers, arrays, functions, etc.). 154 if (!curType->isIntegerType() && !curType->isRealFloatingType()) { 155 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << curType; 156 return; 157 } 158 // unlike gcc's vector_size attribute, the size is specified as the 159 // number of elements, not the number of bytes. 160 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); 161 162 if (vectorSize == 0) { 163 S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 164 << sizeExpr->getSourceRange(); 165 return; 166 } 167 // Instantiate/Install the vector type, the number of elements is > 0. 168 tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize)); 169 // Remember this typedef decl, we will need it later for diagnostics. 170 S.ExtVectorDecls.push_back(tDecl); 171} 172 173 174/// HandleVectorSizeAttribute - this attribute is only applicable to 175/// integral and float scalars, although arrays, pointers, and function 176/// return values are allowed in conjunction with this construct. Aggregates 177/// with this attribute are invalid, even if they are of the same size as a 178/// corresponding scalar. 179/// The raw attribute should contain precisely 1 argument, the vector size 180/// for the variable, measured in bytes. If curType and rawAttr are well 181/// formed, this routine will return a new vector type. 182static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 183 QualType CurType; 184 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 185 CurType = VD->getType(); 186 else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 187 CurType = TD->getUnderlyingType(); 188 else { 189 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 190 << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc()); 191 return; 192 } 193 194 // Check the attribute arugments. 195 if (Attr.getNumArgs() != 1) { 196 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 197 return; 198 } 199 Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 200 llvm::APSInt vecSize(32); 201 if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 202 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 203 << "vector_size" << sizeExpr->getSourceRange(); 204 return; 205 } 206 // navigate to the base type - we need to provide for vector pointers, 207 // vector arrays, and functions returning vectors. 208 if (CurType->isPointerType() || CurType->isArrayType() || 209 CurType->isFunctionType()) { 210 S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType; 211 return; 212 /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 213 do { 214 if (PointerType *PT = dyn_cast<PointerType>(canonType)) 215 canonType = PT->getPointeeType().getTypePtr(); 216 else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 217 canonType = AT->getElementType().getTypePtr(); 218 else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 219 canonType = FT->getResultType().getTypePtr(); 220 } while (canonType->isPointerType() || canonType->isArrayType() || 221 canonType->isFunctionType()); 222 */ 223 } 224 // the base type must be integer or float, and can't already be a vector. 225 if (CurType->isVectorType() || 226 (!CurType->isIntegerType() && !CurType->isRealFloatingType())) { 227 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; 228 return; 229 } 230 unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 231 // vecSize is specified in bytes - convert to bits. 232 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 233 234 // the vector size needs to be an integral multiple of the type size. 235 if (vectorSize % typeSize) { 236 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size) 237 << sizeExpr->getSourceRange(); 238 return; 239 } 240 if (vectorSize == 0) { 241 S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 242 << sizeExpr->getSourceRange(); 243 return; 244 } 245 246 // Success! Instantiate the vector type, the number of elements is > 0, and 247 // not required to be a power of 2, unlike GCC. 248 CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 249 250 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 251 VD->setType(CurType); 252 else 253 cast<TypedefDecl>(D)->setUnderlyingType(CurType); 254} 255 256static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 257 // check the attribute arguments. 258 if (Attr.getNumArgs() > 0) { 259 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 260 return; 261 } 262 263 if (TagDecl *TD = dyn_cast<TagDecl>(d)) 264 TD->addAttr(::new (S.Context) PackedAttr(1)); 265 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 266 // If the alignment is less than or equal to 8 bits, the packed attribute 267 // has no effect. 268 if (!FD->getType()->isIncompleteType() && 269 S.Context.getTypeAlign(FD->getType()) <= 8) 270 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 271 << Attr.getName() << FD->getType(); 272 else 273 FD->addAttr(::new (S.Context) PackedAttr(1)); 274 } else 275 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 276} 277 278static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 279 // check the attribute arguments. 280 if (Attr.getNumArgs() > 0) { 281 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 282 return; 283 } 284 285 // The IBOutlet attribute only applies to instance variables of Objective-C 286 // classes. 287 if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) 288 d->addAttr(::new (S.Context) IBOutletAttr()); 289 else 290 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet); 291} 292 293static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 294 // GCC ignores the nonnull attribute on K&R style function 295 // prototypes, so we ignore it as well 296 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 297 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 298 << Attr.getName() << 0 /*function*/; 299 return; 300 } 301 302 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 303 304 // The nonnull attribute only applies to pointers. 305 llvm::SmallVector<unsigned, 10> NonNullArgs; 306 307 for (AttributeList::arg_iterator I=Attr.arg_begin(), 308 E=Attr.arg_end(); I!=E; ++I) { 309 310 311 // The argument must be an integer constant expression. 312 Expr *Ex = static_cast<Expr *>(*I); 313 llvm::APSInt ArgNum(32); 314 if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 315 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 316 << "nonnull" << Ex->getSourceRange(); 317 return; 318 } 319 320 unsigned x = (unsigned) ArgNum.getZExtValue(); 321 322 if (x < 1 || x > NumArgs) { 323 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 324 << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 325 return; 326 } 327 328 --x; 329 330 // Is the function argument a pointer type? 331 QualType T = getFunctionOrMethodArgType(d, x); 332 if (!T->isPointerType() && !T->isBlockPointerType()) { 333 // FIXME: Should also highlight argument in decl. 334 S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 335 << "nonnull" << Ex->getSourceRange(); 336 continue; 337 } 338 339 NonNullArgs.push_back(x); 340 } 341 342 // If no arguments were specified to __attribute__((nonnull)) then all 343 // pointer arguments have a nonnull attribute. 344 if (NonNullArgs.empty()) { 345 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 346 QualType T = getFunctionOrMethodArgType(d, I); 347 if (T->isPointerType() || T->isBlockPointerType()) 348 NonNullArgs.push_back(I); 349 } 350 351 if (NonNullArgs.empty()) { 352 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 353 return; 354 } 355 } 356 357 unsigned* start = &NonNullArgs[0]; 358 unsigned size = NonNullArgs.size(); 359 std::sort(start, start + size); 360 d->addAttr(::new (S.Context) NonNullAttr(start, size)); 361} 362 363static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 364 // check the attribute arguments. 365 if (Attr.getNumArgs() != 1) { 366 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 367 return; 368 } 369 370 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 371 Arg = Arg->IgnoreParenCasts(); 372 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 373 374 if (Str == 0 || Str->isWide()) { 375 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 376 << "alias" << 1; 377 return; 378 } 379 380 const char *Alias = Str->getStrData(); 381 unsigned AliasLen = Str->getByteLength(); 382 383 // FIXME: check if target symbol exists in current file 384 385 d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen))); 386} 387 388static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 389 Sema &S) { 390 // check the attribute arguments. 391 if (Attr.getNumArgs() != 0) { 392 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 393 return; 394 } 395 396 if (!isa<FunctionDecl>(d)) { 397 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 398 << Attr.getName() << 0 /*function*/; 399 return; 400 } 401 402 d->addAttr(::new (S.Context) AlwaysInlineAttr()); 403} 404 405static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 406 Sema &S) { 407 // check the attribute arguments. 408 if (Attr.getNumArgs() != 0) { 409 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 410 return false; 411 } 412 413 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 414 ValueDecl *VD = dyn_cast<ValueDecl>(d); 415 if (VD == 0 || !VD->getType()->isBlockPointerType()) { 416 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 417 << Attr.getName() << 0 /*function*/; 418 return false; 419 } 420 } 421 422 return true; 423} 424 425static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 426 if (HandleCommonNoReturnAttr(d, Attr, S)) 427 d->addAttr(::new (S.Context) NoReturnAttr()); 428} 429 430static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 431 Sema &S) { 432 if (HandleCommonNoReturnAttr(d, Attr, S)) 433 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 434} 435 436static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 437 // check the attribute arguments. 438 if (Attr.getNumArgs() != 0) { 439 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 440 return; 441 } 442 443 if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 444 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 445 << Attr.getName() << 2 /*variable and function*/; 446 return; 447 } 448 449 d->addAttr(::new (S.Context) UnusedAttr()); 450} 451 452static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 453 // check the attribute arguments. 454 if (Attr.getNumArgs() != 0) { 455 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 456 return; 457 } 458 459 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 460 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 461 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 462 return; 463 } 464 } else if (!isFunctionOrMethod(d)) { 465 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 466 << Attr.getName() << 2 /*variable and function*/; 467 return; 468 } 469 470 d->addAttr(::new (S.Context) UsedAttr()); 471} 472 473static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 474 // check the attribute arguments. 475 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 476 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 477 << "0 or 1"; 478 return; 479 } 480 481 int priority = 65535; // FIXME: Do not hardcode such constants. 482 if (Attr.getNumArgs() > 0) { 483 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 484 llvm::APSInt Idx(32); 485 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 486 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 487 << "constructor" << 1 << E->getSourceRange(); 488 return; 489 } 490 priority = Idx.getZExtValue(); 491 } 492 493 if (!isa<FunctionDecl>(d)) { 494 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 495 << Attr.getName() << 0 /*function*/; 496 return; 497 } 498 499 d->addAttr(::new (S.Context) ConstructorAttr(priority)); 500} 501 502static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 503 // check the attribute arguments. 504 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 505 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 506 << "0 or 1"; 507 return; 508 } 509 510 int priority = 65535; // FIXME: Do not hardcode such constants. 511 if (Attr.getNumArgs() > 0) { 512 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 513 llvm::APSInt Idx(32); 514 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 515 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 516 << "destructor" << 1 << E->getSourceRange(); 517 return; 518 } 519 priority = Idx.getZExtValue(); 520 } 521 522 if (!isa<FunctionDecl>(d)) { 523 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 524 << Attr.getName() << 0 /*function*/; 525 return; 526 } 527 528 d->addAttr(::new (S.Context) DestructorAttr(priority)); 529} 530 531static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 532 // check the attribute arguments. 533 if (Attr.getNumArgs() != 0) { 534 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 535 return; 536 } 537 538 d->addAttr(::new (S.Context) DeprecatedAttr()); 539} 540 541static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 542 // check the attribute arguments. 543 if (Attr.getNumArgs() != 0) { 544 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 545 return; 546 } 547 548 d->addAttr(::new (S.Context) UnavailableAttr()); 549} 550 551static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 552 // check the attribute arguments. 553 if (Attr.getNumArgs() != 1) { 554 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 555 return; 556 } 557 558 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 559 Arg = Arg->IgnoreParenCasts(); 560 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 561 562 if (Str == 0 || Str->isWide()) { 563 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 564 << "visibility" << 1; 565 return; 566 } 567 568 const char *TypeStr = Str->getStrData(); 569 unsigned TypeLen = Str->getByteLength(); 570 VisibilityAttr::VisibilityTypes type; 571 572 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 573 type = VisibilityAttr::DefaultVisibility; 574 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 575 type = VisibilityAttr::HiddenVisibility; 576 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 577 type = VisibilityAttr::HiddenVisibility; // FIXME 578 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 579 type = VisibilityAttr::ProtectedVisibility; 580 else { 581 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 582 return; 583 } 584 585 d->addAttr(::new (S.Context) VisibilityAttr(type)); 586} 587 588static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 589 Sema &S) { 590 if (Attr.getNumArgs() != 0) { 591 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 592 return; 593 } 594 595 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 596 if (OCI == 0) { 597 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 598 return; 599 } 600 601 D->addAttr(::new (S.Context) ObjCExceptionAttr()); 602} 603 604static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 605 if (Attr.getNumArgs() != 0) { 606 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 607 return; 608 } 609 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 610 QualType T = TD->getUnderlyingType(); 611 if (!T->isPointerType() || 612 !T->getAsPointerType()->getPointeeType()->isRecordType()) { 613 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 614 return; 615 } 616 } 617 D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 618} 619 620static void 621HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 622 if (Attr.getNumArgs() != 0) { 623 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 624 return; 625 } 626 627 if (!isa<FunctionDecl>(D)) { 628 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 629 return; 630 } 631 632 D->addAttr(::new (S.Context) OverloadableAttr()); 633} 634 635static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 636 if (!Attr.getParameterName()) { 637 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 638 << "blocks" << 1; 639 return; 640 } 641 642 if (Attr.getNumArgs() != 0) { 643 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 644 return; 645 } 646 647 BlocksAttr::BlocksAttrTypes type; 648 if (Attr.getParameterName()->isStr("byref")) 649 type = BlocksAttr::ByRef; 650 else { 651 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 652 << "blocks" << Attr.getParameterName(); 653 return; 654 } 655 656 d->addAttr(::new (S.Context) BlocksAttr(type)); 657} 658 659static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 660 // check the attribute arguments. 661 if (Attr.getNumArgs() > 2) { 662 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 663 << "0, 1 or 2"; 664 return; 665 } 666 667 int sentinel = 0; 668 if (Attr.getNumArgs() > 0) { 669 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 670 llvm::APSInt Idx(32); 671 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 672 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 673 << "sentinel" << 1 << E->getSourceRange(); 674 return; 675 } 676 sentinel = Idx.getZExtValue(); 677 678 if (sentinel < 0) { 679 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 680 << E->getSourceRange(); 681 return; 682 } 683 } 684 685 int nullPos = 0; 686 if (Attr.getNumArgs() > 1) { 687 Expr *E = static_cast<Expr *>(Attr.getArg(1)); 688 llvm::APSInt Idx(32); 689 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 690 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 691 << "sentinel" << 2 << E->getSourceRange(); 692 return; 693 } 694 nullPos = Idx.getZExtValue(); 695 696 if (nullPos > 1 || nullPos < 0) { 697 // FIXME: This error message could be improved, it would be nice 698 // to say what the bounds actually are. 699 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 700 << E->getSourceRange(); 701 return; 702 } 703 } 704 705 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 706 const FunctionType *FT = FD->getType()->getAsFunctionType(); 707 assert(FT && "FunctionDecl has non-function type?"); 708 709 if (isa<FunctionNoProtoType>(FT)) { 710 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 711 return; 712 } 713 714 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 715 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic); 716 return; 717 } 718 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 719 if (!MD->isVariadic()) { 720 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic); 721 return; 722 } 723 } else { 724 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 725 << Attr.getName() << 3 /*function or method*/; 726 return; 727 } 728 729 // FIXME: Actually create the attribute. 730} 731 732static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 733 // check the attribute arguments. 734 if (Attr.getNumArgs() != 0) { 735 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 736 return; 737 } 738 739 // TODO: could also be applied to methods? 740 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 741 if (!Fn) { 742 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 743 << Attr.getName() << 0 /*function*/; 744 return; 745 } 746 747 Fn->addAttr(::new (S.Context) WarnUnusedResultAttr()); 748} 749 750static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 751 // check the attribute arguments. 752 if (Attr.getNumArgs() != 0) { 753 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 754 return; 755 } 756 757 // TODO: could also be applied to methods? 758 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 759 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 760 << Attr.getName() << 2 /*variable and function*/; 761 return; 762 } 763 764 D->addAttr(::new (S.Context) WeakAttr()); 765} 766 767static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 768 // check the attribute arguments. 769 if (Attr.getNumArgs() != 0) { 770 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 771 return; 772 } 773 774 // weak_import only applies to variable & function declarations. 775 bool isDef = false; 776 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 777 isDef = (!VD->hasExternalStorage() || VD->getInit()); 778 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 779 isDef = FD->getBody(S.Context); 780 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 781 // We ignore weak import on properties and methods 782 return; 783 } else { 784 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 785 << Attr.getName() << 2 /*variable and function*/; 786 return; 787 } 788 789 // Merge should handle any subsequent violations. 790 if (isDef) { 791 S.Diag(Attr.getLoc(), 792 diag::warn_attribute_weak_import_invalid_on_definition) 793 << "weak_import" << 2 /*variable and function*/; 794 return; 795 } 796 797 D->addAttr(::new (S.Context) WeakImportAttr()); 798} 799 800static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 801 // check the attribute arguments. 802 if (Attr.getNumArgs() != 0) { 803 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 804 return; 805 } 806 807 // Attribute can be applied only to functions or variables. 808 if (isa<VarDecl>(D)) { 809 D->addAttr(::new (S.Context) DLLImportAttr()); 810 return; 811 } 812 813 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 814 if (!FD) { 815 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 816 << Attr.getName() << 2 /*variable and function*/; 817 return; 818 } 819 820 // Currently, the dllimport attribute is ignored for inlined functions. 821 // Warning is emitted. 822 if (FD->isInline()) { 823 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 824 return; 825 } 826 827 // The attribute is also overridden by a subsequent declaration as dllexport. 828 // Warning is emitted. 829 for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 830 nextAttr = nextAttr->getNext()) { 831 if (nextAttr->getKind() == AttributeList::AT_dllexport) { 832 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 833 return; 834 } 835 } 836 837 if (D->getAttr<DLLExportAttr>()) { 838 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 839 return; 840 } 841 842 D->addAttr(::new (S.Context) DLLImportAttr()); 843} 844 845static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 846 // check the attribute arguments. 847 if (Attr.getNumArgs() != 0) { 848 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 849 return; 850 } 851 852 // Attribute can be applied only to functions or variables. 853 if (isa<VarDecl>(D)) { 854 D->addAttr(::new (S.Context) DLLExportAttr()); 855 return; 856 } 857 858 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 859 if (!FD) { 860 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 861 << Attr.getName() << 2 /*variable and function*/; 862 return; 863 } 864 865 // Currently, the dllexport attribute is ignored for inlined functions, 866 // unless the -fkeep-inline-functions flag has been used. Warning is emitted; 867 if (FD->isInline()) { 868 // FIXME: ... unless the -fkeep-inline-functions flag has been used. 869 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 870 return; 871 } 872 873 D->addAttr(::new (S.Context) DLLExportAttr()); 874} 875 876static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 877 // Attribute has no arguments. 878 if (Attr.getNumArgs() != 1) { 879 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 880 return; 881 } 882 883 // Make sure that there is a string literal as the sections's single 884 // argument. 885 StringLiteral *SE = 886 dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0))); 887 if (!SE) { 888 // FIXME 889 S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 890 return; 891 } 892 D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(), 893 SE->getByteLength()))); 894} 895 896static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 897 // Attribute has no arguments. 898 if (Attr.getNumArgs() != 0) { 899 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 900 return; 901 } 902 903 // Attribute can be applied only to functions. 904 if (!isa<FunctionDecl>(d)) { 905 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 906 << Attr.getName() << 0 /*function*/; 907 return; 908 } 909 910 // stdcall and fastcall attributes are mutually incompatible. 911 if (d->getAttr<FastCallAttr>()) { 912 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 913 << "stdcall" << "fastcall"; 914 return; 915 } 916 917 d->addAttr(::new (S.Context) StdCallAttr()); 918} 919 920static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 921 // Attribute has no arguments. 922 if (Attr.getNumArgs() != 0) { 923 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 924 return; 925 } 926 927 if (!isa<FunctionDecl>(d)) { 928 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 929 << Attr.getName() << 0 /*function*/; 930 return; 931 } 932 933 // stdcall and fastcall attributes are mutually incompatible. 934 if (d->getAttr<StdCallAttr>()) { 935 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 936 << "fastcall" << "stdcall"; 937 return; 938 } 939 940 d->addAttr(::new (S.Context) FastCallAttr()); 941} 942 943static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 944 // check the attribute arguments. 945 if (Attr.getNumArgs() != 0) { 946 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 947 return; 948 } 949 950 d->addAttr(::new (S.Context) NoThrowAttr()); 951} 952 953static void HandleConstAttr(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 d->addAttr(::new (S.Context) ConstAttr()); 961} 962 963static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 964 // check the attribute arguments. 965 if (Attr.getNumArgs() != 0) { 966 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 967 return; 968 } 969 970 d->addAttr(::new (S.Context) PureAttr()); 971} 972 973static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 974 // Match gcc which ignores cleanup attrs when compiling C++. 975 if (S.getLangOptions().CPlusPlus) 976 return; 977 978 if (!Attr.getParameterName()) { 979 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 980 return; 981 } 982 983 if (Attr.getNumArgs() != 0) { 984 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 985 return; 986 } 987 988 VarDecl *VD = dyn_cast<VarDecl>(d); 989 990 if (!VD || !VD->hasLocalStorage()) { 991 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 992 return; 993 } 994 995 // Look up the function 996 NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), 997 Sema::LookupOrdinaryName); 998 if (!CleanupDecl) { 999 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1000 Attr.getParameterName(); 1001 return; 1002 } 1003 1004 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1005 if (!FD) { 1006 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1007 Attr.getParameterName(); 1008 return; 1009 } 1010 1011 if (FD->getNumParams() != 1) { 1012 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1013 Attr.getParameterName(); 1014 return; 1015 } 1016 1017 // We're currently more strict than GCC about what function types we accept. 1018 // If this ever proves to be a problem it should be easy to fix. 1019 QualType Ty = S.Context.getPointerType(VD->getType()); 1020 QualType ParamTy = FD->getParamDecl(0)->getType(); 1021 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1022 S.Diag(Attr.getLoc(), 1023 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1024 Attr.getParameterName() << ParamTy << Ty; 1025 return; 1026 } 1027 1028 d->addAttr(::new (S.Context) CleanupAttr(FD)); 1029} 1030 1031/// Handle __attribute__((format(type,idx,firstarg))) attributes 1032/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1033static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1034 1035 if (!Attr.getParameterName()) { 1036 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1037 << "format" << 1; 1038 return; 1039 } 1040 1041 if (Attr.getNumArgs() != 2) { 1042 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1043 return; 1044 } 1045 1046 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1047 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1048 << Attr.getName() << 0 /*function*/; 1049 return; 1050 } 1051 1052 // FIXME: in C++ the implicit 'this' function parameter also counts. 1053 // this is needed in order to be compatible with GCC 1054 // the index must start in 1 and the limit is numargs+1 1055 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1056 unsigned FirstIdx = 1; 1057 1058 const char *Format = Attr.getParameterName()->getName(); 1059 unsigned FormatLen = Attr.getParameterName()->getLength(); 1060 1061 // Normalize the argument, __foo__ becomes foo. 1062 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 1063 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 1064 Format += 2; 1065 FormatLen -= 4; 1066 } 1067 1068 bool Supported = false; 1069 bool is_NSString = false; 1070 bool is_strftime = false; 1071 bool is_CFString = false; 1072 1073 switch (FormatLen) { 1074 default: break; 1075 case 5: Supported = !memcmp(Format, "scanf", 5); break; 1076 case 6: Supported = !memcmp(Format, "printf", 6); break; 1077 case 7: Supported = !memcmp(Format, "strfmon", 7); break; 1078 case 8: 1079 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 1080 (is_NSString = !memcmp(Format, "NSString", 8)) || 1081 (is_CFString = !memcmp(Format, "CFString", 8)); 1082 break; 1083 } 1084 1085 if (!Supported) { 1086 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1087 << "format" << Attr.getParameterName()->getName(); 1088 return; 1089 } 1090 1091 // checks for the 2nd argument 1092 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1093 llvm::APSInt Idx(32); 1094 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1095 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1096 << "format" << 2 << IdxExpr->getSourceRange(); 1097 return; 1098 } 1099 1100 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1101 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1102 << "format" << 2 << IdxExpr->getSourceRange(); 1103 return; 1104 } 1105 1106 // FIXME: Do we need to bounds check? 1107 unsigned ArgIdx = Idx.getZExtValue() - 1; 1108 1109 // make sure the format string is really a string 1110 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1111 1112 if (is_CFString) { 1113 if (!isCFStringType(Ty, S.Context)) { 1114 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1115 << "a CFString" << IdxExpr->getSourceRange(); 1116 return; 1117 } 1118 } else if (is_NSString) { 1119 // FIXME: do we need to check if the type is NSString*? What are 1120 // the semantics? 1121 if (!isNSStringType(Ty, S.Context)) { 1122 // FIXME: Should highlight the actual expression that has the 1123 // wrong type. 1124 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1125 << "an NSString" << IdxExpr->getSourceRange(); 1126 return; 1127 } 1128 } else if (!Ty->isPointerType() || 1129 !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 1130 // FIXME: Should highlight the actual expression that has the 1131 // wrong type. 1132 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1133 << "a string type" << IdxExpr->getSourceRange(); 1134 return; 1135 } 1136 1137 // check the 3rd argument 1138 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1139 llvm::APSInt FirstArg(32); 1140 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1141 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1142 << "format" << 3 << FirstArgExpr->getSourceRange(); 1143 return; 1144 } 1145 1146 // check if the function is variadic if the 3rd argument non-zero 1147 if (FirstArg != 0) { 1148 if (isFunctionOrMethodVariadic(d)) { 1149 ++NumArgs; // +1 for ... 1150 } else { 1151 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1152 return; 1153 } 1154 } 1155 1156 // strftime requires FirstArg to be 0 because it doesn't read from any 1157 // variable the input is just the current time + the format string. 1158 if (is_strftime) { 1159 if (FirstArg != 0) { 1160 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1161 << FirstArgExpr->getSourceRange(); 1162 return; 1163 } 1164 // if 0 it disables parameter checking (to use with e.g. va_list) 1165 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1166 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1167 << "format" << 3 << FirstArgExpr->getSourceRange(); 1168 return; 1169 } 1170 1171 d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen), 1172 Idx.getZExtValue(), FirstArg.getZExtValue())); 1173} 1174 1175static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1176 Sema &S) { 1177 // check the attribute arguments. 1178 if (Attr.getNumArgs() != 0) { 1179 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1180 return; 1181 } 1182 1183 // Try to find the underlying union declaration. 1184 RecordDecl *RD = 0; 1185 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1186 if (TD && TD->getUnderlyingType()->isUnionType()) 1187 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1188 else 1189 RD = dyn_cast<RecordDecl>(d); 1190 1191 if (!RD || !RD->isUnion()) { 1192 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1193 << Attr.getName() << 1 /*union*/; 1194 return; 1195 } 1196 1197 if (!RD->isDefinition()) { 1198 S.Diag(Attr.getLoc(), 1199 diag::warn_transparent_union_attribute_not_definition); 1200 return; 1201 } 1202 1203 RecordDecl::field_iterator Field = RD->field_begin(S.Context), 1204 FieldEnd = RD->field_end(S.Context); 1205 if (Field == FieldEnd) { 1206 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1207 return; 1208 } 1209 1210 FieldDecl *FirstField = *Field; 1211 QualType FirstType = FirstField->getType(); 1212 if (FirstType->isFloatingType() || FirstType->isVectorType()) { 1213 S.Diag(FirstField->getLocation(), 1214 diag::warn_transparent_union_attribute_floating); 1215 return; 1216 } 1217 1218 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1219 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1220 for (; Field != FieldEnd; ++Field) { 1221 QualType FieldType = Field->getType(); 1222 if (S.Context.getTypeSize(FieldType) != FirstSize || 1223 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1224 // Warn if we drop the attribute. 1225 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1226 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1227 : S.Context.getTypeAlign(FieldType); 1228 S.Diag(Field->getLocation(), 1229 diag::warn_transparent_union_attribute_field_size_align) 1230 << isSize << Field->getDeclName() << FieldBits; 1231 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1232 S.Diag(FirstField->getLocation(), 1233 diag::note_transparent_union_first_field_size_align) 1234 << isSize << FirstBits; 1235 return; 1236 } 1237 } 1238 1239 RD->addAttr(::new (S.Context) TransparentUnionAttr()); 1240} 1241 1242static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1243 // check the attribute arguments. 1244 if (Attr.getNumArgs() != 1) { 1245 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1246 return; 1247 } 1248 Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 1249 StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 1250 1251 // Make sure that there is a string literal as the annotation's single 1252 // argument. 1253 if (!SE) { 1254 S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 1255 return; 1256 } 1257 d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), 1258 SE->getByteLength()))); 1259} 1260 1261static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1262 // check the attribute arguments. 1263 if (Attr.getNumArgs() > 1) { 1264 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1265 return; 1266 } 1267 1268 unsigned Align = 0; 1269 if (Attr.getNumArgs() == 0) { 1270 // FIXME: This should be the target specific maximum alignment. 1271 // (For now we just use 128 bits which is the maximum on X86). 1272 Align = 128; 1273 d->addAttr(::new (S.Context) AlignedAttr(Align)); 1274 return; 1275 } 1276 1277 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 1278 llvm::APSInt Alignment(32); 1279 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1280 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1281 << "aligned" << alignmentExpr->getSourceRange(); 1282 return; 1283 } 1284 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1285 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1286 << alignmentExpr->getSourceRange(); 1287 return; 1288 } 1289 1290 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 1291} 1292 1293/// HandleModeAttr - This attribute modifies the width of a decl with 1294/// primitive type. 1295/// 1296/// Despite what would be logical, the mode attribute is a decl attribute, 1297/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 1298/// 'G' be HImode, not an intermediate pointer. 1299/// 1300static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1301 // This attribute isn't documented, but glibc uses it. It changes 1302 // the width of an int or unsigned int to the specified size. 1303 1304 // Check that there aren't any arguments 1305 if (Attr.getNumArgs() != 0) { 1306 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1307 return; 1308 } 1309 1310 IdentifierInfo *Name = Attr.getParameterName(); 1311 if (!Name) { 1312 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1313 return; 1314 } 1315 const char *Str = Name->getName(); 1316 unsigned Len = Name->getLength(); 1317 1318 // Normalize the attribute name, __foo__ becomes foo. 1319 if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1320 Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1321 Str += 2; 1322 Len -= 4; 1323 } 1324 1325 unsigned DestWidth = 0; 1326 bool IntegerMode = true; 1327 bool ComplexMode = false; 1328 switch (Len) { 1329 case 2: 1330 switch (Str[0]) { 1331 case 'Q': DestWidth = 8; break; 1332 case 'H': DestWidth = 16; break; 1333 case 'S': DestWidth = 32; break; 1334 case 'D': DestWidth = 64; break; 1335 case 'X': DestWidth = 96; break; 1336 case 'T': DestWidth = 128; break; 1337 } 1338 if (Str[1] == 'F') { 1339 IntegerMode = false; 1340 } else if (Str[1] == 'C') { 1341 IntegerMode = false; 1342 ComplexMode = true; 1343 } else if (Str[1] != 'I') { 1344 DestWidth = 0; 1345 } 1346 break; 1347 case 4: 1348 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1349 // pointer on PIC16 and other embedded platforms. 1350 if (!memcmp(Str, "word", 4)) 1351 DestWidth = S.Context.Target.getPointerWidth(0); 1352 if (!memcmp(Str, "byte", 4)) 1353 DestWidth = S.Context.Target.getCharWidth(); 1354 break; 1355 case 7: 1356 if (!memcmp(Str, "pointer", 7)) 1357 DestWidth = S.Context.Target.getPointerWidth(0); 1358 break; 1359 } 1360 1361 QualType OldTy; 1362 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1363 OldTy = TD->getUnderlyingType(); 1364 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1365 OldTy = VD->getType(); 1366 else { 1367 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1368 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1369 return; 1370 } 1371 1372 if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType()) 1373 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1374 else if (IntegerMode) { 1375 if (!OldTy->isIntegralType()) 1376 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1377 } else if (ComplexMode) { 1378 if (!OldTy->isComplexType()) 1379 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1380 } else { 1381 if (!OldTy->isFloatingType()) 1382 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1383 } 1384 1385 // FIXME: Sync this with InitializePredefinedMacros; we need to match 1386 // int8_t and friends, at least with glibc. 1387 // FIXME: Make sure 32/64-bit integers don't get defined to types of 1388 // the wrong width on unusual platforms. 1389 // FIXME: Make sure floating-point mappings are accurate 1390 // FIXME: Support XF and TF types 1391 QualType NewTy; 1392 switch (DestWidth) { 1393 case 0: 1394 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1395 return; 1396 default: 1397 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1398 return; 1399 case 8: 1400 if (!IntegerMode) { 1401 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1402 return; 1403 } 1404 if (OldTy->isSignedIntegerType()) 1405 NewTy = S.Context.SignedCharTy; 1406 else 1407 NewTy = S.Context.UnsignedCharTy; 1408 break; 1409 case 16: 1410 if (!IntegerMode) { 1411 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1412 return; 1413 } 1414 if (OldTy->isSignedIntegerType()) 1415 NewTy = S.Context.ShortTy; 1416 else 1417 NewTy = S.Context.UnsignedShortTy; 1418 break; 1419 case 32: 1420 if (!IntegerMode) 1421 NewTy = S.Context.FloatTy; 1422 else if (OldTy->isSignedIntegerType()) 1423 NewTy = S.Context.IntTy; 1424 else 1425 NewTy = S.Context.UnsignedIntTy; 1426 break; 1427 case 64: 1428 if (!IntegerMode) 1429 NewTy = S.Context.DoubleTy; 1430 else if (OldTy->isSignedIntegerType()) 1431 NewTy = S.Context.LongLongTy; 1432 else 1433 NewTy = S.Context.UnsignedLongLongTy; 1434 break; 1435 case 96: 1436 NewTy = S.Context.LongDoubleTy; 1437 break; 1438 case 128: 1439 if (!IntegerMode) { 1440 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1441 return; 1442 } 1443 NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 1444 break; 1445 } 1446 1447 if (ComplexMode) { 1448 NewTy = S.Context.getComplexType(NewTy); 1449 } 1450 1451 // Install the new type. 1452 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1453 TD->setUnderlyingType(NewTy); 1454 else 1455 cast<ValueDecl>(D)->setType(NewTy); 1456} 1457 1458static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1459 // check the attribute arguments. 1460 if (Attr.getNumArgs() > 0) { 1461 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1462 return; 1463 } 1464 1465 if (!isFunctionOrMethod(d)) { 1466 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1467 << Attr.getName() << 0 /*function*/; 1468 return; 1469 } 1470 1471 d->addAttr(::new (S.Context) NodebugAttr()); 1472} 1473 1474static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1475 // check the attribute arguments. 1476 if (Attr.getNumArgs() != 0) { 1477 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1478 return; 1479 } 1480 1481 if (!isa<FunctionDecl>(d)) { 1482 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1483 << Attr.getName() << 0 /*function*/; 1484 return; 1485 } 1486 1487 d->addAttr(::new (S.Context) NoinlineAttr()); 1488} 1489 1490static void HandleGNUInlineAttr(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 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1498 if (Fn == 0) { 1499 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1500 << Attr.getName() << 0 /*function*/; 1501 return; 1502 } 1503 1504 if (!Fn->isInline()) { 1505 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1506 return; 1507 } 1508 1509 d->addAttr(::new (S.Context) GNUInlineAttr()); 1510} 1511 1512static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1513 // check the attribute arguments. 1514 if (Attr.getNumArgs() != 1) { 1515 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1516 return; 1517 } 1518 1519 if (!isFunctionOrMethod(d)) { 1520 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1521 << Attr.getName() << 0 /*function*/; 1522 return; 1523 } 1524 1525 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 1526 llvm::APSInt NumParams(32); 1527 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 1528 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1529 << "regparm" << NumParamsExpr->getSourceRange(); 1530 return; 1531 } 1532 1533 if (S.Context.Target.getRegParmMax() == 0) { 1534 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 1535 << NumParamsExpr->getSourceRange(); 1536 return; 1537 } 1538 1539 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1540 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1541 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 1542 return; 1543 } 1544 1545 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1546} 1547 1548//===----------------------------------------------------------------------===// 1549// Checker-specific attribute handlers. 1550//===----------------------------------------------------------------------===// 1551 1552static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1553 Sema &S) { 1554 1555 QualType RetTy; 1556 1557 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 1558 RetTy = MD->getResultType(); 1559 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 1560 RetTy = FD->getResultType(); 1561 else { 1562 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1563 << Attr.getName() << 3 /* function or method */; 1564 return; 1565 } 1566 1567 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAsPointerType())) { 1568 S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type) 1569 << Attr.getName(); 1570 return; 1571 } 1572 1573 switch (Attr.getKind()) { 1574 default: 1575 assert(0 && "invalid ownership attribute"); 1576 return; 1577 case AttributeList::AT_cf_returns_retained: 1578 d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1579 return; 1580 case AttributeList::AT_ns_returns_retained: 1581 d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1582 return; 1583 }; 1584} 1585 1586//===----------------------------------------------------------------------===// 1587// Top Level Sema Entry Points 1588//===----------------------------------------------------------------------===// 1589 1590/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1591/// the attribute applies to decls. If the attribute is a type attribute, just 1592/// silently ignore it. 1593static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 1594 switch (Attr.getKind()) { 1595 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1596 case AttributeList::AT_address_space: 1597 case AttributeList::AT_objc_gc: 1598 // Ignore these, these are type attributes, handled by ProcessTypeAttributes. 1599 break; 1600 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 1601 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1602 case AttributeList::AT_always_inline: 1603 HandleAlwaysInlineAttr (D, Attr, S); break; 1604 case AttributeList::AT_analyzer_noreturn: 1605 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 1606 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 1607 case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1608 case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 1609 case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1610 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 1611 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 1612 case AttributeList::AT_ext_vector_type: 1613 HandleExtVectorTypeAttr(D, Attr, S); 1614 break; 1615 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1616 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1617 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(D, Attr, S); break; 1618 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1619 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 1620 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 1621 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1622 1623 // Checker-specific. 1624 case AttributeList::AT_ns_returns_retained: 1625 case AttributeList::AT_cf_returns_retained: 1626 HandleNSReturnsRetainedAttr(D, Attr, S); break; 1627 1628 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 1629 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 1630 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1631 case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 1632 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1633 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 1634 case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 1635 case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 1636 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1637 break; 1638 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1639 case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; 1640 case AttributeList::AT_transparent_union: 1641 HandleTransparentUnionAttr(D, Attr, S); 1642 break; 1643 case AttributeList::AT_objc_exception: 1644 HandleObjCExceptionAttr(D, Attr, S); 1645 break; 1646 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1647 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 1648 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1649 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1650 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1651 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1652 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1653 case AttributeList::AT_nodebug: HandleNodebugAttr (D, Attr, S); break; 1654 case AttributeList::AT_noinline: HandleNoinlineAttr (D, Attr, S); break; 1655 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1656 case AttributeList::IgnoredAttribute: 1657 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 1658 // Just ignore 1659 break; 1660 default: 1661 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1662 break; 1663 } 1664} 1665 1666/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1667/// attribute list to the specified decl, ignoring any type attributes. 1668void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 1669 while (AttrList) { 1670 ProcessDeclAttribute(D, *AttrList, *this); 1671 AttrList = AttrList->getNext(); 1672 } 1673} 1674 1675/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 1676/// it, apply them to D. This is a bit tricky because PD can have attributes 1677/// specified in many different places, and we need to find and apply them all. 1678void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 1679 // Apply decl attributes from the DeclSpec if present. 1680 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 1681 ProcessDeclAttributeList(D, Attrs); 1682 1683 // Walk the declarator structure, applying decl attributes that were in a type 1684 // position to the decl itself. This handles cases like: 1685 // int *__attr__(x)** D; 1686 // when X is a decl attribute. 1687 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 1688 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 1689 ProcessDeclAttributeList(D, Attrs); 1690 1691 // Finally, apply any attributes on the decl itself. 1692 if (const AttributeList *Attrs = PD.getAttributes()) 1693 ProcessDeclAttributeList(D, Attrs); 1694} 1695