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