SemaDeclAttr.cpp revision 862a2c55c45ffcb0fa3dfa6b8d3dee8d30e305cf
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 (!isFunctionOrMethod(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 void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 404 // check the attribute arguments. 405 if (Attr.getNumArgs() != 0) { 406 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 407 return; 408 } 409 410 if (!isFunctionOrMethod(d)) { 411 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 412 << "noreturn" << 0 /*function*/; 413 return; 414 } 415 416 d->addAttr(::new (S.Context) NoReturnAttr()); 417} 418 419static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 420 // check the attribute arguments. 421 if (Attr.getNumArgs() != 0) { 422 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 423 return; 424 } 425 426 if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 427 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 428 << "unused" << 2 /*variable and function*/; 429 return; 430 } 431 432 d->addAttr(::new (S.Context) UnusedAttr()); 433} 434 435static void HandleUsedAttr(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 (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 443 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 444 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 445 return; 446 } 447 } else if (!isFunctionOrMethod(d)) { 448 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 449 << "used" << 2 /*variable and function*/; 450 return; 451 } 452 453 d->addAttr(::new (S.Context) UsedAttr()); 454} 455 456static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 457 // check the attribute arguments. 458 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 459 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 460 << "0 or 1"; 461 return; 462 } 463 464 int priority = 65535; // FIXME: Do not hardcode such constants. 465 if (Attr.getNumArgs() > 0) { 466 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 467 llvm::APSInt Idx(32); 468 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 469 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 470 << "constructor" << 1 << E->getSourceRange(); 471 return; 472 } 473 priority = Idx.getZExtValue(); 474 } 475 476 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 477 if (!Fn) { 478 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 479 << "constructor" << 0 /*function*/; 480 return; 481 } 482 483 d->addAttr(::new (S.Context) ConstructorAttr(priority)); 484} 485 486static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 487 // check the attribute arguments. 488 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 489 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 490 << "0 or 1"; 491 return; 492 } 493 494 int priority = 65535; // FIXME: Do not hardcode such constants. 495 if (Attr.getNumArgs() > 0) { 496 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 497 llvm::APSInt Idx(32); 498 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 499 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 500 << "destructor" << 1 << E->getSourceRange(); 501 return; 502 } 503 priority = Idx.getZExtValue(); 504 } 505 506 if (!isa<FunctionDecl>(d)) { 507 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 508 << "destructor" << 0 /*function*/; 509 return; 510 } 511 512 d->addAttr(::new (S.Context) DestructorAttr(priority)); 513} 514 515static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 516 // check the attribute arguments. 517 if (Attr.getNumArgs() != 0) { 518 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 519 return; 520 } 521 522 d->addAttr(::new (S.Context) DeprecatedAttr()); 523} 524 525static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 526 // check the attribute arguments. 527 if (Attr.getNumArgs() != 0) { 528 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 529 return; 530 } 531 532 d->addAttr(::new (S.Context) UnavailableAttr()); 533} 534 535static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 536 // check the attribute arguments. 537 if (Attr.getNumArgs() != 1) { 538 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 539 return; 540 } 541 542 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 543 Arg = Arg->IgnoreParenCasts(); 544 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 545 546 if (Str == 0 || Str->isWide()) { 547 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 548 << "visibility" << 1; 549 return; 550 } 551 552 const char *TypeStr = Str->getStrData(); 553 unsigned TypeLen = Str->getByteLength(); 554 VisibilityAttr::VisibilityTypes type; 555 556 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 557 type = VisibilityAttr::DefaultVisibility; 558 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 559 type = VisibilityAttr::HiddenVisibility; 560 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 561 type = VisibilityAttr::HiddenVisibility; // FIXME 562 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 563 type = VisibilityAttr::ProtectedVisibility; 564 else { 565 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 566 return; 567 } 568 569 d->addAttr(::new (S.Context) VisibilityAttr(type)); 570} 571 572static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 573 Sema &S) { 574 if (Attr.getNumArgs() != 0) { 575 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 576 return; 577 } 578 579 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 580 if (OCI == 0) { 581 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 582 return; 583 } 584 585 D->addAttr(::new (S.Context) ObjCExceptionAttr()); 586} 587 588static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 589 if (Attr.getNumArgs() != 0) { 590 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 591 return; 592 } 593 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 594 QualType T = TD->getUnderlyingType(); 595 if (!T->isPointerType() || 596 !T->getAsPointerType()->getPointeeType()->isRecordType()) { 597 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 598 return; 599 } 600 } 601 D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 602} 603 604static void 605HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 606 if (Attr.getNumArgs() != 0) { 607 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 608 return; 609 } 610 611 if (!isa<FunctionDecl>(D)) { 612 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 613 return; 614 } 615 616 D->addAttr(::new (S.Context) OverloadableAttr()); 617} 618 619static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 620 if (!Attr.getParameterName()) { 621 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 622 << "blocks" << 1; 623 return; 624 } 625 626 if (Attr.getNumArgs() != 0) { 627 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 628 return; 629 } 630 631 BlocksAttr::BlocksAttrTypes type; 632 if (Attr.getParameterName()->isStr("byref")) 633 type = BlocksAttr::ByRef; 634 else { 635 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 636 << "blocks" << Attr.getParameterName(); 637 return; 638 } 639 640 d->addAttr(::new (S.Context) BlocksAttr(type)); 641} 642 643static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 644 // check the attribute arguments. 645 if (Attr.getNumArgs() > 2) { 646 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 647 << "0, 1 or 2"; 648 return; 649 } 650 651 int sentinel = 0; 652 if (Attr.getNumArgs() > 0) { 653 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 654 llvm::APSInt Idx(32); 655 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 656 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 657 << "sentinel" << 1 << E->getSourceRange(); 658 return; 659 } 660 sentinel = Idx.getZExtValue(); 661 662 if (sentinel < 0) { 663 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 664 << E->getSourceRange(); 665 return; 666 } 667 } 668 669 int nullPos = 0; 670 if (Attr.getNumArgs() > 1) { 671 Expr *E = static_cast<Expr *>(Attr.getArg(1)); 672 llvm::APSInt Idx(32); 673 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 674 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 675 << "sentinel" << 2 << E->getSourceRange(); 676 return; 677 } 678 nullPos = Idx.getZExtValue(); 679 680 if (nullPos > 1 || nullPos < 0) { 681 // FIXME: This error message could be improved, it would be nice 682 // to say what the bounds actually are. 683 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 684 << E->getSourceRange(); 685 return; 686 } 687 } 688 689 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 690 const FunctionType *FT = FD->getType()->getAsFunctionType(); 691 assert(FT && "FunctionDecl has non-function type?"); 692 693 if (isa<FunctionNoProtoType>(FT)) { 694 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 695 return; 696 } 697 698 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 699 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic); 700 return; 701 } 702 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 703 if (!MD->isVariadic()) { 704 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic); 705 return; 706 } 707 } else { 708 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 709 << "sentinel" << 3 /*function or method*/; 710 return; 711 } 712 713 // FIXME: Actually create the attribute. 714} 715 716static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 717 // check the attribute arguments. 718 if (Attr.getNumArgs() != 0) { 719 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 720 return; 721 } 722 723 // TODO: could also be applied to methods? 724 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 725 if (!Fn) { 726 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 727 << "warn_unused_result" << 0 /*function*/; 728 return; 729 } 730 731 Fn->addAttr(::new (S.Context) WarnUnusedResultAttr()); 732} 733 734static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 735 // check the attribute arguments. 736 if (Attr.getNumArgs() != 0) { 737 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 738 return; 739 } 740 741 // TODO: could also be applied to methods? 742 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 743 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 744 << "weak" << 2 /*variable and function*/; 745 return; 746 } 747 748 D->addAttr(::new (S.Context) WeakAttr()); 749} 750 751static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 752 // check the attribute arguments. 753 if (Attr.getNumArgs() != 0) { 754 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 755 return; 756 } 757 758 // weak_import only applies to variable & function declarations. 759 bool isDef = false; 760 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 761 isDef = (!VD->hasExternalStorage() || VD->getInit()); 762 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 763 isDef = FD->getBody(); 764 } else if (isa<ObjCPropertyDecl>(D)) { 765 // We ignore weak import on properties 766 } else { 767 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 768 << "weak_import" << 2 /*variable and function*/; 769 return; 770 } 771 772 // Merge should handle any subsequent violations. 773 if (isDef) { 774 S.Diag(Attr.getLoc(), 775 diag::warn_attribute_weak_import_invalid_on_definition) 776 << "weak_import" << 2 /*variable and function*/; 777 return; 778 } 779 780 D->addAttr(::new (S.Context) WeakImportAttr()); 781} 782 783static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 784 // check the attribute arguments. 785 if (Attr.getNumArgs() != 0) { 786 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 787 return; 788 } 789 790 // Attribute can be applied only to functions or variables. 791 if (isa<VarDecl>(D)) { 792 D->addAttr(::new (S.Context) DLLImportAttr()); 793 return; 794 } 795 796 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 797 if (!FD) { 798 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 799 << "dllimport" << 2 /*variable and function*/; 800 return; 801 } 802 803 // Currently, the dllimport attribute is ignored for inlined functions. 804 // Warning is emitted. 805 if (FD->isInline()) { 806 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 807 return; 808 } 809 810 // The attribute is also overridden by a subsequent declaration as dllexport. 811 // Warning is emitted. 812 for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 813 nextAttr = nextAttr->getNext()) { 814 if (nextAttr->getKind() == AttributeList::AT_dllexport) { 815 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 816 return; 817 } 818 } 819 820 if (D->getAttr<DLLExportAttr>()) { 821 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 822 return; 823 } 824 825 D->addAttr(::new (S.Context) DLLImportAttr()); 826} 827 828static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 829 // check the attribute arguments. 830 if (Attr.getNumArgs() != 0) { 831 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 832 return; 833 } 834 835 // Attribute can be applied only to functions or variables. 836 if (isa<VarDecl>(D)) { 837 D->addAttr(::new (S.Context) DLLExportAttr()); 838 return; 839 } 840 841 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 842 if (!FD) { 843 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 844 << "dllexport" << 2 /*variable and function*/; 845 return; 846 } 847 848 // Currently, the dllexport attribute is ignored for inlined functions, 849 // unless the -fkeep-inline-functions flag has been used. Warning is emitted; 850 if (FD->isInline()) { 851 // FIXME: ... unless the -fkeep-inline-functions flag has been used. 852 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 853 return; 854 } 855 856 D->addAttr(::new (S.Context) DLLExportAttr()); 857} 858 859static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 860 // Attribute has no arguments. 861 if (Attr.getNumArgs() != 1) { 862 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 863 return; 864 } 865 866 // Make sure that there is a string literal as the sections's single 867 // argument. 868 StringLiteral *SE = 869 dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0))); 870 if (!SE) { 871 // FIXME 872 S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 873 return; 874 } 875 D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(), 876 SE->getByteLength()))); 877} 878 879static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 880 // Attribute has no arguments. 881 if (Attr.getNumArgs() != 0) { 882 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 883 return; 884 } 885 886 // Attribute can be applied only to functions. 887 if (!isa<FunctionDecl>(d)) { 888 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 889 << "stdcall" << 0 /*function*/; 890 return; 891 } 892 893 // stdcall and fastcall attributes are mutually incompatible. 894 if (d->getAttr<FastCallAttr>()) { 895 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 896 << "stdcall" << "fastcall"; 897 return; 898 } 899 900 d->addAttr(::new (S.Context) StdCallAttr()); 901} 902 903static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 904 // Attribute has no arguments. 905 if (Attr.getNumArgs() != 0) { 906 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 907 return; 908 } 909 910 if (!isa<FunctionDecl>(d)) { 911 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 912 << "fastcall" << 0 /*function*/; 913 return; 914 } 915 916 // stdcall and fastcall attributes are mutually incompatible. 917 if (d->getAttr<StdCallAttr>()) { 918 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 919 << "fastcall" << "stdcall"; 920 return; 921 } 922 923 d->addAttr(::new (S.Context) FastCallAttr()); 924} 925 926static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 927 // check the attribute arguments. 928 if (Attr.getNumArgs() != 0) { 929 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 930 return; 931 } 932 933 d->addAttr(::new (S.Context) NoThrowAttr()); 934} 935 936static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 937 // check the attribute arguments. 938 if (Attr.getNumArgs() != 0) { 939 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 940 return; 941 } 942 943 d->addAttr(::new (S.Context) ConstAttr()); 944} 945 946static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 947 // check the attribute arguments. 948 if (Attr.getNumArgs() != 0) { 949 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 950 return; 951 } 952 953 d->addAttr(::new (S.Context) PureAttr()); 954} 955 956static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 957 // Match gcc which ignores cleanup attrs when compiling C++. 958 if (S.getLangOptions().CPlusPlus) 959 return; 960 961 if (!Attr.getParameterName()) { 962 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 963 return; 964 } 965 966 if (Attr.getNumArgs() != 0) { 967 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 968 return; 969 } 970 971 VarDecl *VD = dyn_cast<VarDecl>(d); 972 973 if (!VD || !VD->hasLocalStorage()) { 974 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 975 return; 976 } 977 978 // Look up the function 979 NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), 980 Sema::LookupOrdinaryName); 981 if (!CleanupDecl) { 982 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 983 Attr.getParameterName(); 984 return; 985 } 986 987 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 988 if (!FD) { 989 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 990 Attr.getParameterName(); 991 return; 992 } 993 994 if (FD->getNumParams() != 1) { 995 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 996 Attr.getParameterName(); 997 return; 998 } 999 1000 // We're currently more strict than GCC about what function types we accept. 1001 // If this ever proves to be a problem it should be easy to fix. 1002 QualType Ty = S.Context.getPointerType(VD->getType()); 1003 QualType ParamTy = FD->getParamDecl(0)->getType(); 1004 if (S.CheckAssignmentConstraints(Ty, ParamTy) != Sema::Compatible) { 1005 S.Diag(Attr.getLoc(), 1006 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1007 Attr.getParameterName() << ParamTy << Ty; 1008 return; 1009 } 1010 1011 d->addAttr(::new (S.Context) CleanupAttr(FD)); 1012} 1013 1014/// Handle __attribute__((format(type,idx,firstarg))) attributes 1015/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1016static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1017 1018 if (!Attr.getParameterName()) { 1019 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1020 << "format" << 1; 1021 return; 1022 } 1023 1024 if (Attr.getNumArgs() != 2) { 1025 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1026 return; 1027 } 1028 1029 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1030 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1031 << "format" << 0 /*function*/; 1032 return; 1033 } 1034 1035 // FIXME: in C++ the implicit 'this' function parameter also counts. 1036 // this is needed in order to be compatible with GCC 1037 // the index must start in 1 and the limit is numargs+1 1038 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1039 unsigned FirstIdx = 1; 1040 1041 const char *Format = Attr.getParameterName()->getName(); 1042 unsigned FormatLen = Attr.getParameterName()->getLength(); 1043 1044 // Normalize the argument, __foo__ becomes foo. 1045 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 1046 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 1047 Format += 2; 1048 FormatLen -= 4; 1049 } 1050 1051 bool Supported = false; 1052 bool is_NSString = false; 1053 bool is_strftime = false; 1054 bool is_CFString = false; 1055 1056 switch (FormatLen) { 1057 default: break; 1058 case 5: Supported = !memcmp(Format, "scanf", 5); break; 1059 case 6: Supported = !memcmp(Format, "printf", 6); break; 1060 case 7: Supported = !memcmp(Format, "strfmon", 7); break; 1061 case 8: 1062 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 1063 (is_NSString = !memcmp(Format, "NSString", 8)) || 1064 (is_CFString = !memcmp(Format, "CFString", 8)); 1065 break; 1066 } 1067 1068 if (!Supported) { 1069 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1070 << "format" << Attr.getParameterName()->getName(); 1071 return; 1072 } 1073 1074 // checks for the 2nd argument 1075 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1076 llvm::APSInt Idx(32); 1077 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1078 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1079 << "format" << 2 << IdxExpr->getSourceRange(); 1080 return; 1081 } 1082 1083 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1084 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1085 << "format" << 2 << IdxExpr->getSourceRange(); 1086 return; 1087 } 1088 1089 // FIXME: Do we need to bounds check? 1090 unsigned ArgIdx = Idx.getZExtValue() - 1; 1091 1092 // make sure the format string is really a string 1093 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1094 1095 if (is_CFString) { 1096 if (!isCFStringType(Ty, S.Context)) { 1097 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1098 << "a CFString" << IdxExpr->getSourceRange(); 1099 return; 1100 } 1101 } else if (is_NSString) { 1102 // FIXME: do we need to check if the type is NSString*? What are 1103 // the semantics? 1104 if (!isNSStringType(Ty, S.Context)) { 1105 // FIXME: Should highlight the actual expression that has the 1106 // wrong type. 1107 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1108 << "an NSString" << IdxExpr->getSourceRange(); 1109 return; 1110 } 1111 } else if (!Ty->isPointerType() || 1112 !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 1113 // FIXME: Should highlight the actual expression that has the 1114 // wrong type. 1115 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1116 << "a string type" << IdxExpr->getSourceRange(); 1117 return; 1118 } 1119 1120 // check the 3rd argument 1121 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1122 llvm::APSInt FirstArg(32); 1123 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1124 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1125 << "format" << 3 << FirstArgExpr->getSourceRange(); 1126 return; 1127 } 1128 1129 // check if the function is variadic if the 3rd argument non-zero 1130 if (FirstArg != 0) { 1131 if (isFunctionOrMethodVariadic(d)) { 1132 ++NumArgs; // +1 for ... 1133 } else { 1134 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1135 return; 1136 } 1137 } 1138 1139 // strftime requires FirstArg to be 0 because it doesn't read from any 1140 // variable the input is just the current time + the format string. 1141 if (is_strftime) { 1142 if (FirstArg != 0) { 1143 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1144 << FirstArgExpr->getSourceRange(); 1145 return; 1146 } 1147 // if 0 it disables parameter checking (to use with e.g. va_list) 1148 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1149 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1150 << "format" << 3 << FirstArgExpr->getSourceRange(); 1151 return; 1152 } 1153 1154 d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen), 1155 Idx.getZExtValue(), FirstArg.getZExtValue())); 1156} 1157 1158static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1159 Sema &S) { 1160 // check the attribute arguments. 1161 if (Attr.getNumArgs() != 0) { 1162 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1163 return; 1164 } 1165 1166 // FIXME: This shouldn't be restricted to typedefs 1167 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1168 if (!TD || !TD->getUnderlyingType()->isUnionType()) { 1169 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1170 << "transparent_union" << 1 /*union*/; 1171 return; 1172 } 1173 1174 RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1175 1176 // FIXME: Should we do a check for RD->isDefinition()? 1177 1178 // FIXME: This isn't supposed to be restricted to pointers, but otherwise 1179 // we might silently generate incorrect code; see following code 1180 for (RecordDecl::field_iterator Field = RD->field_begin(), 1181 FieldEnd = RD->field_end(); 1182 Field != FieldEnd; ++Field) { 1183 if (!Field->getType()->isPointerType()) { 1184 S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer); 1185 return; 1186 } 1187 } 1188 1189 // FIXME: This is a complete hack; we should be properly propagating 1190 // transparent_union through Sema. That said, this is close enough to 1191 // correctly compile all the common cases of transparent_union without 1192 // errors or warnings 1193 QualType NewTy = S.Context.VoidPtrTy; 1194 NewTy.addConst(); 1195 TD->setUnderlyingType(NewTy); 1196} 1197 1198static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1199 // check the attribute arguments. 1200 if (Attr.getNumArgs() != 1) { 1201 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1202 return; 1203 } 1204 Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 1205 StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 1206 1207 // Make sure that there is a string literal as the annotation's single 1208 // argument. 1209 if (!SE) { 1210 S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 1211 return; 1212 } 1213 d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), 1214 SE->getByteLength()))); 1215} 1216 1217static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1218 // check the attribute arguments. 1219 if (Attr.getNumArgs() > 1) { 1220 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1221 return; 1222 } 1223 1224 unsigned Align = 0; 1225 if (Attr.getNumArgs() == 0) { 1226 // FIXME: This should be the target specific maximum alignment. 1227 // (For now we just use 128 bits which is the maximum on X86). 1228 Align = 128; 1229 d->addAttr(::new (S.Context) AlignedAttr(Align)); 1230 return; 1231 } 1232 1233 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 1234 llvm::APSInt Alignment(32); 1235 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1236 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1237 << "aligned" << alignmentExpr->getSourceRange(); 1238 return; 1239 } 1240 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1241 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1242 << alignmentExpr->getSourceRange(); 1243 return; 1244 } 1245 1246 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 1247} 1248 1249/// HandleModeAttr - This attribute modifies the width of a decl with 1250/// primitive type. 1251/// 1252/// Despite what would be logical, the mode attribute is a decl attribute, 1253/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 1254/// 'G' be HImode, not an intermediate pointer. 1255/// 1256static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1257 // This attribute isn't documented, but glibc uses it. It changes 1258 // the width of an int or unsigned int to the specified size. 1259 1260 // Check that there aren't any arguments 1261 if (Attr.getNumArgs() != 0) { 1262 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1263 return; 1264 } 1265 1266 IdentifierInfo *Name = Attr.getParameterName(); 1267 if (!Name) { 1268 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1269 return; 1270 } 1271 const char *Str = Name->getName(); 1272 unsigned Len = Name->getLength(); 1273 1274 // Normalize the attribute name, __foo__ becomes foo. 1275 if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1276 Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1277 Str += 2; 1278 Len -= 4; 1279 } 1280 1281 unsigned DestWidth = 0; 1282 bool IntegerMode = true; 1283 bool ComplexMode = false; 1284 switch (Len) { 1285 case 2: 1286 switch (Str[0]) { 1287 case 'Q': DestWidth = 8; break; 1288 case 'H': DestWidth = 16; break; 1289 case 'S': DestWidth = 32; break; 1290 case 'D': DestWidth = 64; break; 1291 case 'X': DestWidth = 96; break; 1292 case 'T': DestWidth = 128; break; 1293 } 1294 if (Str[1] == 'F') { 1295 IntegerMode = false; 1296 } else if (Str[1] == 'C') { 1297 IntegerMode = false; 1298 ComplexMode = true; 1299 } else if (Str[1] != 'I') { 1300 DestWidth = 0; 1301 } 1302 break; 1303 case 4: 1304 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1305 // pointer on PIC16 and other embedded platforms. 1306 if (!memcmp(Str, "word", 4)) 1307 DestWidth = S.Context.Target.getPointerWidth(0); 1308 if (!memcmp(Str, "byte", 4)) 1309 DestWidth = S.Context.Target.getCharWidth(); 1310 break; 1311 case 7: 1312 if (!memcmp(Str, "pointer", 7)) 1313 DestWidth = S.Context.Target.getPointerWidth(0); 1314 break; 1315 } 1316 1317 QualType OldTy; 1318 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1319 OldTy = TD->getUnderlyingType(); 1320 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1321 OldTy = VD->getType(); 1322 else { 1323 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1324 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1325 return; 1326 } 1327 1328 if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType()) 1329 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1330 else if (IntegerMode) { 1331 if (!OldTy->isIntegralType()) 1332 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1333 } else if (ComplexMode) { 1334 if (!OldTy->isComplexType()) 1335 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1336 } else { 1337 if (!OldTy->isFloatingType()) 1338 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1339 } 1340 1341 // FIXME: Sync this with InitializePredefinedMacros; we need to match 1342 // int8_t and friends, at least with glibc. 1343 // FIXME: Make sure 32/64-bit integers don't get defined to types of 1344 // the wrong width on unusual platforms. 1345 // FIXME: Make sure floating-point mappings are accurate 1346 // FIXME: Support XF and TF types 1347 QualType NewTy; 1348 switch (DestWidth) { 1349 case 0: 1350 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1351 return; 1352 default: 1353 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1354 return; 1355 case 8: 1356 if (!IntegerMode) { 1357 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1358 return; 1359 } 1360 if (OldTy->isSignedIntegerType()) 1361 NewTy = S.Context.SignedCharTy; 1362 else 1363 NewTy = S.Context.UnsignedCharTy; 1364 break; 1365 case 16: 1366 if (!IntegerMode) { 1367 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1368 return; 1369 } 1370 if (OldTy->isSignedIntegerType()) 1371 NewTy = S.Context.ShortTy; 1372 else 1373 NewTy = S.Context.UnsignedShortTy; 1374 break; 1375 case 32: 1376 if (!IntegerMode) 1377 NewTy = S.Context.FloatTy; 1378 else if (OldTy->isSignedIntegerType()) 1379 NewTy = S.Context.IntTy; 1380 else 1381 NewTy = S.Context.UnsignedIntTy; 1382 break; 1383 case 64: 1384 if (!IntegerMode) 1385 NewTy = S.Context.DoubleTy; 1386 else if (OldTy->isSignedIntegerType()) 1387 NewTy = S.Context.LongLongTy; 1388 else 1389 NewTy = S.Context.UnsignedLongLongTy; 1390 break; 1391 case 96: 1392 NewTy = S.Context.LongDoubleTy; 1393 break; 1394 case 128: 1395 if (!IntegerMode) { 1396 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1397 return; 1398 } 1399 NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 1400 break; 1401 } 1402 1403 if (ComplexMode) { 1404 NewTy = S.Context.getComplexType(NewTy); 1405 } 1406 1407 // Install the new type. 1408 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1409 TD->setUnderlyingType(NewTy); 1410 else 1411 cast<ValueDecl>(D)->setType(NewTy); 1412} 1413 1414static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1415 // check the attribute arguments. 1416 if (Attr.getNumArgs() > 0) { 1417 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1418 return; 1419 } 1420 1421 if (!isFunctionOrMethod(d)) { 1422 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1423 << "nodebug" << 0 /*function*/; 1424 return; 1425 } 1426 1427 d->addAttr(::new (S.Context) NodebugAttr()); 1428} 1429 1430static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1431 // check the attribute arguments. 1432 if (Attr.getNumArgs() != 0) { 1433 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1434 return; 1435 } 1436 1437 if (!isFunctionOrMethod(d)) { 1438 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1439 << "noinline" << 0 /*function*/; 1440 return; 1441 } 1442 1443 d->addAttr(::new (S.Context) NoinlineAttr()); 1444} 1445 1446//===----------------------------------------------------------------------===// 1447// Top Level Sema Entry Points 1448//===----------------------------------------------------------------------===// 1449 1450/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1451/// the attribute applies to decls. If the attribute is a type attribute, just 1452/// silently ignore it. 1453static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 1454 switch (Attr.getKind()) { 1455 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1456 case AttributeList::AT_address_space: 1457 case AttributeList::AT_objc_gc: 1458 // Ignore these, these are type attributes, handled by ProcessTypeAttributes. 1459 break; 1460 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 1461 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1462 case AttributeList::AT_always_inline: 1463 HandleAlwaysInlineAttr (D, Attr, S); break; 1464 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 1465 case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1466 case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 1467 case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1468 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 1469 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 1470 case AttributeList::AT_ext_vector_type: 1471 HandleExtVectorTypeAttr(D, Attr, S); 1472 break; 1473 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1474 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1475 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1476 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 1477 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 1478 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1479 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 1480 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 1481 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1482 case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 1483 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1484 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 1485 case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 1486 case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 1487 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1488 break; 1489 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1490 case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; 1491 case AttributeList::AT_transparent_union: 1492 HandleTransparentUnionAttr(D, Attr, S); 1493 break; 1494 case AttributeList::AT_objc_exception: 1495 HandleObjCExceptionAttr(D, Attr, S); 1496 break; 1497 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1498 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 1499 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1500 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1501 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1502 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1503 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1504 case AttributeList::AT_nodebug: HandleNodebugAttr (D, Attr, S); break; 1505 case AttributeList::AT_noinline: HandleNoinlineAttr (D, Attr, S); break; 1506 case AttributeList::IgnoredAttribute: 1507 // Just ignore 1508 break; 1509 default: 1510 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1511 break; 1512 } 1513} 1514 1515/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1516/// attribute list to the specified decl, ignoring any type attributes. 1517void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 1518 while (AttrList) { 1519 ProcessDeclAttribute(D, *AttrList, *this); 1520 AttrList = AttrList->getNext(); 1521 } 1522} 1523 1524 1525/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 1526/// it, apply them to D. This is a bit tricky because PD can have attributes 1527/// specified in many different places, and we need to find and apply them all. 1528void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 1529 // Apply decl attributes from the DeclSpec if present. 1530 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 1531 ProcessDeclAttributeList(D, Attrs); 1532 1533 // Walk the declarator structure, applying decl attributes that were in a type 1534 // position to the decl itself. This handles cases like: 1535 // int *__attr__(x)** D; 1536 // when X is a decl attribute. 1537 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 1538 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 1539 ProcessDeclAttributeList(D, Attrs); 1540 1541 // Finally, apply any attributes on the decl itself. 1542 if (const AttributeList *Attrs = PD.getAttributes()) 1543 ProcessDeclAttributeList(D, Attrs); 1544} 1545 1546