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