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