SemaDeclAttr.cpp revision 1102f4282ceb430dbc9fcedb9dd2ad25898a09e8
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 return; 767 } else { 768 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 769 << "weak_import" << 2 /*variable and function*/; 770 return; 771 } 772 773 // Merge should handle any subsequent violations. 774 if (isDef) { 775 S.Diag(Attr.getLoc(), 776 diag::warn_attribute_weak_import_invalid_on_definition) 777 << "weak_import" << 2 /*variable and function*/; 778 return; 779 } 780 781 D->addAttr(::new (S.Context) WeakImportAttr()); 782} 783 784static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 785 // check the attribute arguments. 786 if (Attr.getNumArgs() != 0) { 787 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 788 return; 789 } 790 791 // Attribute can be applied only to functions or variables. 792 if (isa<VarDecl>(D)) { 793 D->addAttr(::new (S.Context) DLLImportAttr()); 794 return; 795 } 796 797 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 798 if (!FD) { 799 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 800 << "dllimport" << 2 /*variable and function*/; 801 return; 802 } 803 804 // Currently, the dllimport attribute is ignored for inlined functions. 805 // Warning is emitted. 806 if (FD->isInline()) { 807 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 808 return; 809 } 810 811 // The attribute is also overridden by a subsequent declaration as dllexport. 812 // Warning is emitted. 813 for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 814 nextAttr = nextAttr->getNext()) { 815 if (nextAttr->getKind() == AttributeList::AT_dllexport) { 816 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 817 return; 818 } 819 } 820 821 if (D->getAttr<DLLExportAttr>()) { 822 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 823 return; 824 } 825 826 D->addAttr(::new (S.Context) DLLImportAttr()); 827} 828 829static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 830 // check the attribute arguments. 831 if (Attr.getNumArgs() != 0) { 832 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 833 return; 834 } 835 836 // Attribute can be applied only to functions or variables. 837 if (isa<VarDecl>(D)) { 838 D->addAttr(::new (S.Context) DLLExportAttr()); 839 return; 840 } 841 842 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 843 if (!FD) { 844 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 845 << "dllexport" << 2 /*variable and function*/; 846 return; 847 } 848 849 // Currently, the dllexport attribute is ignored for inlined functions, 850 // unless the -fkeep-inline-functions flag has been used. Warning is emitted; 851 if (FD->isInline()) { 852 // FIXME: ... unless the -fkeep-inline-functions flag has been used. 853 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 854 return; 855 } 856 857 D->addAttr(::new (S.Context) DLLExportAttr()); 858} 859 860static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 861 // Attribute has no arguments. 862 if (Attr.getNumArgs() != 1) { 863 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 864 return; 865 } 866 867 // Make sure that there is a string literal as the sections's single 868 // argument. 869 StringLiteral *SE = 870 dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0))); 871 if (!SE) { 872 // FIXME 873 S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 874 return; 875 } 876 D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(), 877 SE->getByteLength()))); 878} 879 880static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 881 // Attribute has no arguments. 882 if (Attr.getNumArgs() != 0) { 883 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 884 return; 885 } 886 887 // Attribute can be applied only to functions. 888 if (!isa<FunctionDecl>(d)) { 889 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 890 << "stdcall" << 0 /*function*/; 891 return; 892 } 893 894 // stdcall and fastcall attributes are mutually incompatible. 895 if (d->getAttr<FastCallAttr>()) { 896 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 897 << "stdcall" << "fastcall"; 898 return; 899 } 900 901 d->addAttr(::new (S.Context) StdCallAttr()); 902} 903 904static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 905 // Attribute has no arguments. 906 if (Attr.getNumArgs() != 0) { 907 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 908 return; 909 } 910 911 if (!isa<FunctionDecl>(d)) { 912 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 913 << "fastcall" << 0 /*function*/; 914 return; 915 } 916 917 // stdcall and fastcall attributes are mutually incompatible. 918 if (d->getAttr<StdCallAttr>()) { 919 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 920 << "fastcall" << "stdcall"; 921 return; 922 } 923 924 d->addAttr(::new (S.Context) FastCallAttr()); 925} 926 927static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 928 // check the attribute arguments. 929 if (Attr.getNumArgs() != 0) { 930 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 931 return; 932 } 933 934 d->addAttr(::new (S.Context) NoThrowAttr()); 935} 936 937static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 938 // check the attribute arguments. 939 if (Attr.getNumArgs() != 0) { 940 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 941 return; 942 } 943 944 d->addAttr(::new (S.Context) ConstAttr()); 945} 946 947static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 948 // check the attribute arguments. 949 if (Attr.getNumArgs() != 0) { 950 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 951 return; 952 } 953 954 d->addAttr(::new (S.Context) PureAttr()); 955} 956 957static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 958 // Match gcc which ignores cleanup attrs when compiling C++. 959 if (S.getLangOptions().CPlusPlus) 960 return; 961 962 if (!Attr.getParameterName()) { 963 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 964 return; 965 } 966 967 if (Attr.getNumArgs() != 0) { 968 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 969 return; 970 } 971 972 VarDecl *VD = dyn_cast<VarDecl>(d); 973 974 if (!VD || !VD->hasLocalStorage()) { 975 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 976 return; 977 } 978 979 // Look up the function 980 NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), 981 Sema::LookupOrdinaryName); 982 if (!CleanupDecl) { 983 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 984 Attr.getParameterName(); 985 return; 986 } 987 988 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 989 if (!FD) { 990 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 991 Attr.getParameterName(); 992 return; 993 } 994 995 if (FD->getNumParams() != 1) { 996 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 997 Attr.getParameterName(); 998 return; 999 } 1000 1001 // We're currently more strict than GCC about what function types we accept. 1002 // If this ever proves to be a problem it should be easy to fix. 1003 QualType Ty = S.Context.getPointerType(VD->getType()); 1004 QualType ParamTy = FD->getParamDecl(0)->getType(); 1005 if (S.CheckAssignmentConstraints(Ty, ParamTy) != Sema::Compatible) { 1006 S.Diag(Attr.getLoc(), 1007 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1008 Attr.getParameterName() << ParamTy << Ty; 1009 return; 1010 } 1011 1012 d->addAttr(::new (S.Context) CleanupAttr(FD)); 1013} 1014 1015/// Handle __attribute__((format(type,idx,firstarg))) attributes 1016/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1017static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1018 1019 if (!Attr.getParameterName()) { 1020 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1021 << "format" << 1; 1022 return; 1023 } 1024 1025 if (Attr.getNumArgs() != 2) { 1026 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1027 return; 1028 } 1029 1030 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1031 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1032 << "format" << 0 /*function*/; 1033 return; 1034 } 1035 1036 // FIXME: in C++ the implicit 'this' function parameter also counts. 1037 // this is needed in order to be compatible with GCC 1038 // the index must start in 1 and the limit is numargs+1 1039 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1040 unsigned FirstIdx = 1; 1041 1042 const char *Format = Attr.getParameterName()->getName(); 1043 unsigned FormatLen = Attr.getParameterName()->getLength(); 1044 1045 // Normalize the argument, __foo__ becomes foo. 1046 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 1047 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 1048 Format += 2; 1049 FormatLen -= 4; 1050 } 1051 1052 bool Supported = false; 1053 bool is_NSString = false; 1054 bool is_strftime = false; 1055 bool is_CFString = false; 1056 1057 switch (FormatLen) { 1058 default: break; 1059 case 5: Supported = !memcmp(Format, "scanf", 5); break; 1060 case 6: Supported = !memcmp(Format, "printf", 6); break; 1061 case 7: Supported = !memcmp(Format, "strfmon", 7); break; 1062 case 8: 1063 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 1064 (is_NSString = !memcmp(Format, "NSString", 8)) || 1065 (is_CFString = !memcmp(Format, "CFString", 8)); 1066 break; 1067 } 1068 1069 if (!Supported) { 1070 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1071 << "format" << Attr.getParameterName()->getName(); 1072 return; 1073 } 1074 1075 // checks for the 2nd argument 1076 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1077 llvm::APSInt Idx(32); 1078 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1079 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1080 << "format" << 2 << IdxExpr->getSourceRange(); 1081 return; 1082 } 1083 1084 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1085 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1086 << "format" << 2 << IdxExpr->getSourceRange(); 1087 return; 1088 } 1089 1090 // FIXME: Do we need to bounds check? 1091 unsigned ArgIdx = Idx.getZExtValue() - 1; 1092 1093 // make sure the format string is really a string 1094 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1095 1096 if (is_CFString) { 1097 if (!isCFStringType(Ty, S.Context)) { 1098 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1099 << "a CFString" << IdxExpr->getSourceRange(); 1100 return; 1101 } 1102 } else if (is_NSString) { 1103 // FIXME: do we need to check if the type is NSString*? What are 1104 // the semantics? 1105 if (!isNSStringType(Ty, S.Context)) { 1106 // FIXME: Should highlight the actual expression that has the 1107 // wrong type. 1108 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1109 << "an NSString" << IdxExpr->getSourceRange(); 1110 return; 1111 } 1112 } else if (!Ty->isPointerType() || 1113 !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 1114 // FIXME: Should highlight the actual expression that has the 1115 // wrong type. 1116 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1117 << "a string type" << IdxExpr->getSourceRange(); 1118 return; 1119 } 1120 1121 // check the 3rd argument 1122 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1123 llvm::APSInt FirstArg(32); 1124 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1125 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1126 << "format" << 3 << FirstArgExpr->getSourceRange(); 1127 return; 1128 } 1129 1130 // check if the function is variadic if the 3rd argument non-zero 1131 if (FirstArg != 0) { 1132 if (isFunctionOrMethodVariadic(d)) { 1133 ++NumArgs; // +1 for ... 1134 } else { 1135 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1136 return; 1137 } 1138 } 1139 1140 // strftime requires FirstArg to be 0 because it doesn't read from any 1141 // variable the input is just the current time + the format string. 1142 if (is_strftime) { 1143 if (FirstArg != 0) { 1144 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1145 << FirstArgExpr->getSourceRange(); 1146 return; 1147 } 1148 // if 0 it disables parameter checking (to use with e.g. va_list) 1149 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1150 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1151 << "format" << 3 << FirstArgExpr->getSourceRange(); 1152 return; 1153 } 1154 1155 d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen), 1156 Idx.getZExtValue(), FirstArg.getZExtValue())); 1157} 1158 1159static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1160 Sema &S) { 1161 // check the attribute arguments. 1162 if (Attr.getNumArgs() != 0) { 1163 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1164 return; 1165 } 1166 1167 // FIXME: This shouldn't be restricted to typedefs 1168 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1169 if (!TD || !TD->getUnderlyingType()->isUnionType()) { 1170 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1171 << "transparent_union" << 1 /*union*/; 1172 return; 1173 } 1174 1175 RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1176 1177 // FIXME: Should we do a check for RD->isDefinition()? 1178 1179 // FIXME: This isn't supposed to be restricted to pointers, but otherwise 1180 // we might silently generate incorrect code; see following code 1181 for (RecordDecl::field_iterator Field = RD->field_begin(), 1182 FieldEnd = RD->field_end(); 1183 Field != FieldEnd; ++Field) { 1184 if (!Field->getType()->isPointerType()) { 1185 S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer); 1186 return; 1187 } 1188 } 1189 1190 // FIXME: This is a complete hack; we should be properly propagating 1191 // transparent_union through Sema. That said, this is close enough to 1192 // correctly compile all the common cases of transparent_union without 1193 // errors or warnings 1194 QualType NewTy = S.Context.VoidPtrTy; 1195 NewTy.addConst(); 1196 TD->setUnderlyingType(NewTy); 1197} 1198 1199static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1200 // check the attribute arguments. 1201 if (Attr.getNumArgs() != 1) { 1202 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1203 return; 1204 } 1205 Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 1206 StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 1207 1208 // Make sure that there is a string literal as the annotation's single 1209 // argument. 1210 if (!SE) { 1211 S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 1212 return; 1213 } 1214 d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), 1215 SE->getByteLength()))); 1216} 1217 1218static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1219 // check the attribute arguments. 1220 if (Attr.getNumArgs() > 1) { 1221 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1222 return; 1223 } 1224 1225 unsigned Align = 0; 1226 if (Attr.getNumArgs() == 0) { 1227 // FIXME: This should be the target specific maximum alignment. 1228 // (For now we just use 128 bits which is the maximum on X86). 1229 Align = 128; 1230 d->addAttr(::new (S.Context) AlignedAttr(Align)); 1231 return; 1232 } 1233 1234 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 1235 llvm::APSInt Alignment(32); 1236 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1237 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1238 << "aligned" << alignmentExpr->getSourceRange(); 1239 return; 1240 } 1241 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1242 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1243 << alignmentExpr->getSourceRange(); 1244 return; 1245 } 1246 1247 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 1248} 1249 1250/// HandleModeAttr - This attribute modifies the width of a decl with 1251/// primitive type. 1252/// 1253/// Despite what would be logical, the mode attribute is a decl attribute, 1254/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 1255/// 'G' be HImode, not an intermediate pointer. 1256/// 1257static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1258 // This attribute isn't documented, but glibc uses it. It changes 1259 // the width of an int or unsigned int to the specified size. 1260 1261 // Check that there aren't any arguments 1262 if (Attr.getNumArgs() != 0) { 1263 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1264 return; 1265 } 1266 1267 IdentifierInfo *Name = Attr.getParameterName(); 1268 if (!Name) { 1269 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1270 return; 1271 } 1272 const char *Str = Name->getName(); 1273 unsigned Len = Name->getLength(); 1274 1275 // Normalize the attribute name, __foo__ becomes foo. 1276 if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1277 Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1278 Str += 2; 1279 Len -= 4; 1280 } 1281 1282 unsigned DestWidth = 0; 1283 bool IntegerMode = true; 1284 bool ComplexMode = false; 1285 switch (Len) { 1286 case 2: 1287 switch (Str[0]) { 1288 case 'Q': DestWidth = 8; break; 1289 case 'H': DestWidth = 16; break; 1290 case 'S': DestWidth = 32; break; 1291 case 'D': DestWidth = 64; break; 1292 case 'X': DestWidth = 96; break; 1293 case 'T': DestWidth = 128; break; 1294 } 1295 if (Str[1] == 'F') { 1296 IntegerMode = false; 1297 } else if (Str[1] == 'C') { 1298 IntegerMode = false; 1299 ComplexMode = true; 1300 } else if (Str[1] != 'I') { 1301 DestWidth = 0; 1302 } 1303 break; 1304 case 4: 1305 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1306 // pointer on PIC16 and other embedded platforms. 1307 if (!memcmp(Str, "word", 4)) 1308 DestWidth = S.Context.Target.getPointerWidth(0); 1309 if (!memcmp(Str, "byte", 4)) 1310 DestWidth = S.Context.Target.getCharWidth(); 1311 break; 1312 case 7: 1313 if (!memcmp(Str, "pointer", 7)) 1314 DestWidth = S.Context.Target.getPointerWidth(0); 1315 break; 1316 } 1317 1318 QualType OldTy; 1319 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1320 OldTy = TD->getUnderlyingType(); 1321 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1322 OldTy = VD->getType(); 1323 else { 1324 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1325 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1326 return; 1327 } 1328 1329 if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType()) 1330 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1331 else if (IntegerMode) { 1332 if (!OldTy->isIntegralType()) 1333 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1334 } else if (ComplexMode) { 1335 if (!OldTy->isComplexType()) 1336 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1337 } else { 1338 if (!OldTy->isFloatingType()) 1339 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1340 } 1341 1342 // FIXME: Sync this with InitializePredefinedMacros; we need to match 1343 // int8_t and friends, at least with glibc. 1344 // FIXME: Make sure 32/64-bit integers don't get defined to types of 1345 // the wrong width on unusual platforms. 1346 // FIXME: Make sure floating-point mappings are accurate 1347 // FIXME: Support XF and TF types 1348 QualType NewTy; 1349 switch (DestWidth) { 1350 case 0: 1351 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1352 return; 1353 default: 1354 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1355 return; 1356 case 8: 1357 if (!IntegerMode) { 1358 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1359 return; 1360 } 1361 if (OldTy->isSignedIntegerType()) 1362 NewTy = S.Context.SignedCharTy; 1363 else 1364 NewTy = S.Context.UnsignedCharTy; 1365 break; 1366 case 16: 1367 if (!IntegerMode) { 1368 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1369 return; 1370 } 1371 if (OldTy->isSignedIntegerType()) 1372 NewTy = S.Context.ShortTy; 1373 else 1374 NewTy = S.Context.UnsignedShortTy; 1375 break; 1376 case 32: 1377 if (!IntegerMode) 1378 NewTy = S.Context.FloatTy; 1379 else if (OldTy->isSignedIntegerType()) 1380 NewTy = S.Context.IntTy; 1381 else 1382 NewTy = S.Context.UnsignedIntTy; 1383 break; 1384 case 64: 1385 if (!IntegerMode) 1386 NewTy = S.Context.DoubleTy; 1387 else if (OldTy->isSignedIntegerType()) 1388 NewTy = S.Context.LongLongTy; 1389 else 1390 NewTy = S.Context.UnsignedLongLongTy; 1391 break; 1392 case 96: 1393 NewTy = S.Context.LongDoubleTy; 1394 break; 1395 case 128: 1396 if (!IntegerMode) { 1397 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1398 return; 1399 } 1400 NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 1401 break; 1402 } 1403 1404 if (ComplexMode) { 1405 NewTy = S.Context.getComplexType(NewTy); 1406 } 1407 1408 // Install the new type. 1409 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1410 TD->setUnderlyingType(NewTy); 1411 else 1412 cast<ValueDecl>(D)->setType(NewTy); 1413} 1414 1415static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1416 // check the attribute arguments. 1417 if (Attr.getNumArgs() > 0) { 1418 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1419 return; 1420 } 1421 1422 if (!isFunctionOrMethod(d)) { 1423 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1424 << "nodebug" << 0 /*function*/; 1425 return; 1426 } 1427 1428 d->addAttr(::new (S.Context) NodebugAttr()); 1429} 1430 1431static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1432 // check the attribute arguments. 1433 if (Attr.getNumArgs() != 0) { 1434 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1435 return; 1436 } 1437 1438 if (!isFunctionOrMethod(d)) { 1439 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1440 << "noinline" << 0 /*function*/; 1441 return; 1442 } 1443 1444 d->addAttr(::new (S.Context) NoinlineAttr()); 1445} 1446 1447static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1448 // check the attribute arguments. 1449 if (Attr.getNumArgs() != 1) { 1450 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1451 return; 1452 } 1453 1454 if (!isFunctionOrMethod(d)) { 1455 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1456 << "regparm" << 0 /*function*/; 1457 return; 1458 } 1459 1460 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 1461 llvm::APSInt NumParams(32); 1462 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 1463 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1464 << "regparm" << NumParamsExpr->getSourceRange(); 1465 return; 1466 } 1467 1468 if (S.Context.Target.getRegParmMax() == 0) { 1469 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 1470 << NumParamsExpr->getSourceRange(); 1471 return; 1472 } 1473 1474 if (NumParams.getLimitedValue(4) > S.Context.Target.getRegParmMax()) { 1475 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1476 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 1477 return; 1478 } 1479 1480 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1481} 1482 1483//===----------------------------------------------------------------------===// 1484// Top Level Sema Entry Points 1485//===----------------------------------------------------------------------===// 1486 1487/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1488/// the attribute applies to decls. If the attribute is a type attribute, just 1489/// silently ignore it. 1490static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 1491 switch (Attr.getKind()) { 1492 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1493 case AttributeList::AT_address_space: 1494 case AttributeList::AT_objc_gc: 1495 // Ignore these, these are type attributes, handled by ProcessTypeAttributes. 1496 break; 1497 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 1498 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1499 case AttributeList::AT_always_inline: 1500 HandleAlwaysInlineAttr (D, Attr, S); break; 1501 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 1502 case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1503 case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 1504 case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1505 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 1506 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 1507 case AttributeList::AT_ext_vector_type: 1508 HandleExtVectorTypeAttr(D, Attr, S); 1509 break; 1510 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1511 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1512 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1513 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 1514 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 1515 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1516 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 1517 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 1518 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1519 case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 1520 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1521 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 1522 case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 1523 case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 1524 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1525 break; 1526 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1527 case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; 1528 case AttributeList::AT_transparent_union: 1529 HandleTransparentUnionAttr(D, Attr, S); 1530 break; 1531 case AttributeList::AT_objc_exception: 1532 HandleObjCExceptionAttr(D, Attr, S); 1533 break; 1534 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1535 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 1536 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1537 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1538 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1539 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1540 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1541 case AttributeList::AT_nodebug: HandleNodebugAttr (D, Attr, S); break; 1542 case AttributeList::AT_noinline: HandleNoinlineAttr (D, Attr, S); break; 1543 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1544 case AttributeList::IgnoredAttribute: 1545 // Just ignore 1546 break; 1547 default: 1548 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1549 break; 1550 } 1551} 1552 1553/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1554/// attribute list to the specified decl, ignoring any type attributes. 1555void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 1556 while (AttrList) { 1557 ProcessDeclAttribute(D, *AttrList, *this); 1558 AttrList = AttrList->getNext(); 1559 } 1560} 1561 1562 1563/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 1564/// it, apply them to D. This is a bit tricky because PD can have attributes 1565/// specified in many different places, and we need to find and apply them all. 1566void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 1567 // Apply decl attributes from the DeclSpec if present. 1568 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 1569 ProcessDeclAttributeList(D, Attrs); 1570 1571 // Walk the declarator structure, applying decl attributes that were in a type 1572 // position to the decl itself. This handles cases like: 1573 // int *__attr__(x)** D; 1574 // when X is a decl attribute. 1575 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 1576 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 1577 ProcessDeclAttributeList(D, Attrs); 1578 1579 // Finally, apply any attributes on the decl itself. 1580 if (const AttributeList *Attrs = PD.getAttributes()) 1581 ProcessDeclAttributeList(D, Attrs); 1582} 1583 1584