clang API Documentation
00001 //===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements decl-related attribute processing. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "Sema.h" 00015 #include "TargetAttributesSema.h" 00016 #include "clang/AST/ASTContext.h" 00017 #include "clang/AST/DeclObjC.h" 00018 #include "clang/AST/Expr.h" 00019 #include "clang/Basic/TargetInfo.h" 00020 #include "clang/Parse/DeclSpec.h" 00021 #include "llvm/ADT/StringExtras.h" 00022 using namespace clang; 00023 00024 //===----------------------------------------------------------------------===// 00025 // Helper functions 00026 //===----------------------------------------------------------------------===// 00027 00028 static const FunctionType *getFunctionType(const Decl *d, 00029 bool blocksToo = true) { 00030 QualType Ty; 00031 if (const ValueDecl *decl = dyn_cast<ValueDecl>(d)) 00032 Ty = decl->getType(); 00033 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d)) 00034 Ty = decl->getType(); 00035 else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 00036 Ty = decl->getUnderlyingType(); 00037 else 00038 return 0; 00039 00040 if (Ty->isFunctionPointerType()) 00041 Ty = Ty->getAs<PointerType>()->getPointeeType(); 00042 else if (blocksToo && Ty->isBlockPointerType()) 00043 Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 00044 00045 return Ty->getAs<FunctionType>(); 00046 } 00047 00048 // FIXME: We should provide an abstraction around a method or function 00049 // to provide the following bits of information. 00050 00051 /// isFunction - Return true if the given decl has function 00052 /// type (function or function-typed variable). 00053 static bool isFunction(const Decl *d) { 00054 return getFunctionType(d, false) != NULL; 00055 } 00056 00057 /// isFunctionOrMethod - Return true if the given decl has function 00058 /// type (function or function-typed variable) or an Objective-C 00059 /// method. 00060 static bool isFunctionOrMethod(const Decl *d) { 00061 return isFunction(d)|| isa<ObjCMethodDecl>(d); 00062 } 00063 00064 /// isFunctionOrMethodOrBlock - Return true if the given decl has function 00065 /// type (function or function-typed variable) or an Objective-C 00066 /// method or a block. 00067 static bool isFunctionOrMethodOrBlock(const Decl *d) { 00068 if (isFunctionOrMethod(d)) 00069 return true; 00070 // check for block is more involved. 00071 if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 00072 QualType Ty = V->getType(); 00073 return Ty->isBlockPointerType(); 00074 } 00075 return isa<BlockDecl>(d); 00076 } 00077 00078 /// hasFunctionProto - Return true if the given decl has a argument 00079 /// information. This decl should have already passed 00080 /// isFunctionOrMethod or isFunctionOrMethodOrBlock. 00081 static bool hasFunctionProto(const Decl *d) { 00082 if (const FunctionType *FnTy = getFunctionType(d)) 00083 return isa<FunctionProtoType>(FnTy); 00084 else { 00085 assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 00086 return true; 00087 } 00088 } 00089 00090 /// getFunctionOrMethodNumArgs - Return number of function or method 00091 /// arguments. It is an error to call this on a K&R function (use 00092 /// hasFunctionProto first). 00093 static unsigned getFunctionOrMethodNumArgs(const Decl *d) { 00094 if (const FunctionType *FnTy = getFunctionType(d)) 00095 return cast<FunctionProtoType>(FnTy)->getNumArgs(); 00096 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 00097 return BD->getNumParams(); 00098 return cast<ObjCMethodDecl>(d)->param_size(); 00099 } 00100 00101 static QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) { 00102 if (const FunctionType *FnTy = getFunctionType(d)) 00103 return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 00104 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 00105 return BD->getParamDecl(Idx)->getType(); 00106 00107 return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 00108 } 00109 00110 static QualType getFunctionOrMethodResultType(const Decl *d) { 00111 if (const FunctionType *FnTy = getFunctionType(d)) 00112 return cast<FunctionProtoType>(FnTy)->getResultType(); 00113 return cast<ObjCMethodDecl>(d)->getResultType(); 00114 } 00115 00116 static bool isFunctionOrMethodVariadic(const Decl *d) { 00117 if (const FunctionType *FnTy = getFunctionType(d)) { 00118 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 00119 return proto->isVariadic(); 00120 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 00121 return BD->isVariadic(); 00122 else { 00123 return cast<ObjCMethodDecl>(d)->isVariadic(); 00124 } 00125 } 00126 00127 static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 00128 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 00129 if (!PT) 00130 return false; 00131 00132 const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAs<ObjCInterfaceType>(); 00133 if (!ClsT) 00134 return false; 00135 00136 IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 00137 00138 // FIXME: Should we walk the chain of classes? 00139 return ClsName == &Ctx.Idents.get("NSString") || 00140 ClsName == &Ctx.Idents.get("NSMutableString"); 00141 } 00142 00143 static inline bool isCFStringType(QualType T, ASTContext &Ctx) { 00144 const PointerType *PT = T->getAs<PointerType>(); 00145 if (!PT) 00146 return false; 00147 00148 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 00149 if (!RT) 00150 return false; 00151 00152 const RecordDecl *RD = RT->getDecl(); 00153 if (RD->getTagKind() != TagDecl::TK_struct) 00154 return false; 00155 00156 return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 00157 } 00158 00159 //===----------------------------------------------------------------------===// 00160 // Attribute Implementations 00161 //===----------------------------------------------------------------------===// 00162 00163 // FIXME: All this manual attribute parsing code is gross. At the 00164 // least add some helper functions to check most argument patterns (# 00165 // and types of args). 00166 00167 static void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 00168 const AttributeList &Attr, Sema &S) { 00169 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 00170 if (tDecl == 0) { 00171 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 00172 return; 00173 } 00174 00175 QualType curType = tDecl->getUnderlyingType(); 00176 00177 Expr *sizeExpr; 00178 00179 // Special case where the argument is a template id. 00180 if (Attr.getParameterName()) { 00181 CXXScopeSpec SS; 00182 UnqualifiedId id; 00183 id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 00184 sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); 00185 } else { 00186 // check the attribute arguments. 00187 if (Attr.getNumArgs() != 1) { 00188 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 00189 return; 00190 } 00191 sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 00192 } 00193 00194 // Instantiate/Install the vector type, and let Sema build the type for us. 00195 // This will run the reguired checks. 00196 QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc()); 00197 if (!T.isNull()) { 00198 // FIXME: preserve the old source info. 00199 tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 00200 00201 // Remember this typedef decl, we will need it later for diagnostics. 00202 S.ExtVectorDecls.push_back(tDecl); 00203 } 00204 } 00205 00206 static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00207 // check the attribute arguments. 00208 if (Attr.getNumArgs() > 0) { 00209 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00210 return; 00211 } 00212 00213 if (TagDecl *TD = dyn_cast<TagDecl>(d)) 00214 TD->addAttr(::new (S.Context) PackedAttr); 00215 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 00216 // If the alignment is less than or equal to 8 bits, the packed attribute 00217 // has no effect. 00218 if (!FD->getType()->isIncompleteType() && 00219 S.Context.getTypeAlign(FD->getType()) <= 8) 00220 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 00221 << Attr.getName() << FD->getType(); 00222 else 00223 FD->addAttr(::new (S.Context) PackedAttr); 00224 } else 00225 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 00226 } 00227 00228 static void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) { 00229 // check the attribute arguments. 00230 if (Attr.getNumArgs() > 0) { 00231 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00232 return; 00233 } 00234 00235 // The IBAction attributes only apply to instance methods. 00236 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 00237 if (MD->isInstanceMethod()) { 00238 d->addAttr(::new (S.Context) IBActionAttr()); 00239 return; 00240 } 00241 00242 S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName(); 00243 } 00244 00245 static void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) { 00246 // check the attribute arguments. 00247 if (Attr.getNumArgs() > 0) { 00248 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00249 return; 00250 } 00251 00252 // The IBOutlet attributes only apply to instance variables of 00253 // Objective-C classes. 00254 if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) { 00255 d->addAttr(::new (S.Context) IBOutletAttr()); 00256 return; 00257 } 00258 00259 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 00260 } 00261 00262 static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00263 // GCC ignores the nonnull attribute on K&R style function prototypes, so we 00264 // ignore it as well 00265 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 00266 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00267 << Attr.getName() << 0 /*function*/; 00268 return; 00269 } 00270 00271 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 00272 00273 // The nonnull attribute only applies to pointers. 00274 llvm::SmallVector<unsigned, 10> NonNullArgs; 00275 00276 for (AttributeList::arg_iterator I=Attr.arg_begin(), 00277 E=Attr.arg_end(); I!=E; ++I) { 00278 00279 00280 // The argument must be an integer constant expression. 00281 Expr *Ex = static_cast<Expr *>(*I); 00282 llvm::APSInt ArgNum(32); 00283 if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 00284 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 00285 << "nonnull" << Ex->getSourceRange(); 00286 return; 00287 } 00288 00289 unsigned x = (unsigned) ArgNum.getZExtValue(); 00290 00291 if (x < 1 || x > NumArgs) { 00292 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 00293 << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 00294 return; 00295 } 00296 00297 --x; 00298 00299 // Is the function argument a pointer type? 00300 QualType T = getFunctionOrMethodArgType(d, x); 00301 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 00302 // FIXME: Should also highlight argument in decl. 00303 S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 00304 << "nonnull" << Ex->getSourceRange(); 00305 continue; 00306 } 00307 00308 NonNullArgs.push_back(x); 00309 } 00310 00311 // If no arguments were specified to __attribute__((nonnull)) then all pointer 00312 // arguments have a nonnull attribute. 00313 if (NonNullArgs.empty()) { 00314 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 00315 QualType T = getFunctionOrMethodArgType(d, I); 00316 if (T->isAnyPointerType() || T->isBlockPointerType()) 00317 NonNullArgs.push_back(I); 00318 } 00319 00320 if (NonNullArgs.empty()) { 00321 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 00322 return; 00323 } 00324 } 00325 00326 unsigned* start = &NonNullArgs[0]; 00327 unsigned size = NonNullArgs.size(); 00328 std::sort(start, start + size); 00329 d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size)); 00330 } 00331 00332 static bool isStaticVarOrStaticFunciton(Decl *D) { 00333 if (VarDecl *VD = dyn_cast<VarDecl>(D)) 00334 return VD->getStorageClass() == VarDecl::Static; 00335 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 00336 return FD->getStorageClass() == FunctionDecl::Static; 00337 return false; 00338 } 00339 00340 static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00341 // Check the attribute arguments. 00342 if (Attr.getNumArgs() > 1) { 00343 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 00344 return; 00345 } 00346 00347 // gcc rejects 00348 // class c { 00349 // static int a __attribute__((weakref ("v2"))); 00350 // static int b() __attribute__((weakref ("f3"))); 00351 // }; 00352 // and ignores the attributes of 00353 // void f(void) { 00354 // static int a __attribute__((weakref ("v2"))); 00355 // } 00356 // we reject them 00357 if (const DeclContext *Ctx = d->getDeclContext()) { 00358 Ctx = Ctx->getLookupContext(); 00359 if (!isa<TranslationUnitDecl>(Ctx) && !isa<NamespaceDecl>(Ctx) ) { 00360 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 00361 dyn_cast<NamedDecl>(d)->getNameAsString(); 00362 return; 00363 } 00364 } 00365 00366 // The GCC manual says 00367 // 00368 // At present, a declaration to which `weakref' is attached can only 00369 // be `static'. 00370 // 00371 // It also says 00372 // 00373 // Without a TARGET, 00374 // given as an argument to `weakref' or to `alias', `weakref' is 00375 // equivalent to `weak'. 00376 // 00377 // gcc 4.4.1 will accept 00378 // int a7 __attribute__((weakref)); 00379 // as 00380 // int a7 __attribute__((weak)); 00381 // This looks like a bug in gcc. We reject that for now. We should revisit 00382 // it if this behaviour is actually used. 00383 00384 if (!isStaticVarOrStaticFunciton(d)) { 00385 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) << 00386 dyn_cast<NamedDecl>(d)->getNameAsString(); 00387 return; 00388 } 00389 00390 // GCC rejects 00391 // static ((alias ("y"), weakref)). 00392 // Should we? How to check that weakref is before or after alias? 00393 00394 if (Attr.getNumArgs() == 1) { 00395 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 00396 Arg = Arg->IgnoreParenCasts(); 00397 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 00398 00399 if (Str == 0 || Str->isWide()) { 00400 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 00401 << "weakref" << 1; 00402 return; 00403 } 00404 // GCC will accept anything as the argument of weakref. Should we 00405 // check for an existing decl? 00406 d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString())); 00407 } 00408 00409 d->addAttr(::new (S.Context) WeakRefAttr()); 00410 } 00411 00412 static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00413 // check the attribute arguments. 00414 if (Attr.getNumArgs() != 1) { 00415 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 00416 return; 00417 } 00418 00419 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 00420 Arg = Arg->IgnoreParenCasts(); 00421 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 00422 00423 if (Str == 0 || Str->isWide()) { 00424 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 00425 << "alias" << 1; 00426 return; 00427 } 00428 00429 // FIXME: check if target symbol exists in current file 00430 00431 d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString())); 00432 } 00433 00434 static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 00435 Sema &S) { 00436 // check the attribute arguments. 00437 if (Attr.getNumArgs() != 0) { 00438 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00439 return; 00440 } 00441 00442 if (!isa<FunctionDecl>(d)) { 00443 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00444 << Attr.getName() << 0 /*function*/; 00445 return; 00446 } 00447 00448 d->addAttr(::new (S.Context) AlwaysInlineAttr()); 00449 } 00450 00451 static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00452 // check the attribute arguments. 00453 if (Attr.getNumArgs() != 0) { 00454 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00455 return; 00456 } 00457 00458 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 00459 QualType RetTy = FD->getResultType(); 00460 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 00461 d->addAttr(::new (S.Context) MallocAttr()); 00462 return; 00463 } 00464 } 00465 00466 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 00467 } 00468 00469 static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 00470 Sema &S) { 00471 // check the attribute arguments. 00472 if (Attr.getNumArgs() != 0) { 00473 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00474 return false; 00475 } 00476 00477 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 00478 ValueDecl *VD = dyn_cast<ValueDecl>(d); 00479 if (VD == 0 || (!VD->getType()->isBlockPointerType() 00480 && !VD->getType()->isFunctionPointerType())) { 00481 S.Diag(Attr.getLoc(), 00482 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 00483 : diag::warn_attribute_wrong_decl_type) 00484 << Attr.getName() << 0 /*function*/; 00485 return false; 00486 } 00487 } 00488 00489 return true; 00490 } 00491 00492 static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00493 /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */ 00494 assert(Attr.isInvalid() == false); 00495 d->addAttr(::new (S.Context) NoReturnAttr()); 00496 } 00497 00498 static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 00499 Sema &S) { 00500 if (HandleCommonNoReturnAttr(d, Attr, S)) 00501 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 00502 } 00503 00504 static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00505 if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 00506 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 00507 << Attr.getName() << 8 /*function, method, or parameter*/; 00508 return; 00509 } 00510 // FIXME: Actually store the attribute on the declaration 00511 } 00512 00513 static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00514 // check the attribute arguments. 00515 if (Attr.getNumArgs() != 0) { 00516 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00517 return; 00518 } 00519 00520 if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) && 00521 !isa<TypeDecl>(d)) { 00522 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00523 << Attr.getName() << 2 /*variable and function*/; 00524 return; 00525 } 00526 00527 d->addAttr(::new (S.Context) UnusedAttr()); 00528 } 00529 00530 static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00531 // check the attribute arguments. 00532 if (Attr.getNumArgs() != 0) { 00533 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00534 return; 00535 } 00536 00537 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 00538 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 00539 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 00540 return; 00541 } 00542 } else if (!isFunctionOrMethod(d)) { 00543 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00544 << Attr.getName() << 2 /*variable and function*/; 00545 return; 00546 } 00547 00548 d->addAttr(::new (S.Context) UsedAttr()); 00549 } 00550 00551 static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00552 // check the attribute arguments. 00553 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 00554 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 00555 << "0 or 1"; 00556 return; 00557 } 00558 00559 int priority = 65535; // FIXME: Do not hardcode such constants. 00560 if (Attr.getNumArgs() > 0) { 00561 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 00562 llvm::APSInt Idx(32); 00563 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 00564 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 00565 << "constructor" << 1 << E->getSourceRange(); 00566 return; 00567 } 00568 priority = Idx.getZExtValue(); 00569 } 00570 00571 if (!isa<FunctionDecl>(d)) { 00572 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00573 << Attr.getName() << 0 /*function*/; 00574 return; 00575 } 00576 00577 d->addAttr(::new (S.Context) ConstructorAttr(priority)); 00578 } 00579 00580 static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00581 // check the attribute arguments. 00582 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 00583 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 00584 << "0 or 1"; 00585 return; 00586 } 00587 00588 int priority = 65535; // FIXME: Do not hardcode such constants. 00589 if (Attr.getNumArgs() > 0) { 00590 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 00591 llvm::APSInt Idx(32); 00592 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 00593 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 00594 << "destructor" << 1 << E->getSourceRange(); 00595 return; 00596 } 00597 priority = Idx.getZExtValue(); 00598 } 00599 00600 if (!isa<FunctionDecl>(d)) { 00601 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00602 << Attr.getName() << 0 /*function*/; 00603 return; 00604 } 00605 00606 d->addAttr(::new (S.Context) DestructorAttr(priority)); 00607 } 00608 00609 static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00610 // check the attribute arguments. 00611 if (Attr.getNumArgs() != 0) { 00612 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00613 return; 00614 } 00615 00616 d->addAttr(::new (S.Context) DeprecatedAttr()); 00617 } 00618 00619 static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00620 // check the attribute arguments. 00621 if (Attr.getNumArgs() != 0) { 00622 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00623 return; 00624 } 00625 00626 d->addAttr(::new (S.Context) UnavailableAttr()); 00627 } 00628 00629 static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00630 // check the attribute arguments. 00631 if (Attr.getNumArgs() != 1) { 00632 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 00633 return; 00634 } 00635 00636 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 00637 Arg = Arg->IgnoreParenCasts(); 00638 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 00639 00640 if (Str == 0 || Str->isWide()) { 00641 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 00642 << "visibility" << 1; 00643 return; 00644 } 00645 00646 llvm::StringRef TypeStr = Str->getString(); 00647 VisibilityAttr::VisibilityTypes type; 00648 00649 if (TypeStr == "default") 00650 type = VisibilityAttr::DefaultVisibility; 00651 else if (TypeStr == "hidden") 00652 type = VisibilityAttr::HiddenVisibility; 00653 else if (TypeStr == "internal") 00654 type = VisibilityAttr::HiddenVisibility; // FIXME 00655 else if (TypeStr == "protected") 00656 type = VisibilityAttr::ProtectedVisibility; 00657 else { 00658 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 00659 return; 00660 } 00661 00662 d->addAttr(::new (S.Context) VisibilityAttr(type)); 00663 } 00664 00665 static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 00666 Sema &S) { 00667 if (Attr.getNumArgs() != 0) { 00668 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00669 return; 00670 } 00671 00672 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 00673 if (OCI == 0) { 00674 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 00675 return; 00676 } 00677 00678 D->addAttr(::new (S.Context) ObjCExceptionAttr()); 00679 } 00680 00681 static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 00682 if (Attr.getNumArgs() != 0) { 00683 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 00684 return; 00685 } 00686 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 00687 QualType T = TD->getUnderlyingType(); 00688 if (!T->isPointerType() || 00689 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 00690 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 00691 return; 00692 } 00693 } 00694 D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 00695 } 00696 00697 static void 00698 HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 00699 if (Attr.getNumArgs() != 0) { 00700 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 00701 return; 00702 } 00703 00704 if (!isa<FunctionDecl>(D)) { 00705 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 00706 return; 00707 } 00708 00709 D->addAttr(::new (S.Context) OverloadableAttr()); 00710 } 00711 00712 static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00713 if (!Attr.getParameterName()) { 00714 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 00715 << "blocks" << 1; 00716 return; 00717 } 00718 00719 if (Attr.getNumArgs() != 0) { 00720 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 00721 return; 00722 } 00723 00724 BlocksAttr::BlocksAttrTypes type; 00725 if (Attr.getParameterName()->isStr("byref")) 00726 type = BlocksAttr::ByRef; 00727 else { 00728 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 00729 << "blocks" << Attr.getParameterName(); 00730 return; 00731 } 00732 00733 d->addAttr(::new (S.Context) BlocksAttr(type)); 00734 } 00735 00736 static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00737 // check the attribute arguments. 00738 if (Attr.getNumArgs() > 2) { 00739 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 00740 << "0, 1 or 2"; 00741 return; 00742 } 00743 00744 int sentinel = 0; 00745 if (Attr.getNumArgs() > 0) { 00746 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 00747 llvm::APSInt Idx(32); 00748 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 00749 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 00750 << "sentinel" << 1 << E->getSourceRange(); 00751 return; 00752 } 00753 sentinel = Idx.getZExtValue(); 00754 00755 if (sentinel < 0) { 00756 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 00757 << E->getSourceRange(); 00758 return; 00759 } 00760 } 00761 00762 int nullPos = 0; 00763 if (Attr.getNumArgs() > 1) { 00764 Expr *E = static_cast<Expr *>(Attr.getArg(1)); 00765 llvm::APSInt Idx(32); 00766 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 00767 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 00768 << "sentinel" << 2 << E->getSourceRange(); 00769 return; 00770 } 00771 nullPos = Idx.getZExtValue(); 00772 00773 if (nullPos > 1 || nullPos < 0) { 00774 // FIXME: This error message could be improved, it would be nice 00775 // to say what the bounds actually are. 00776 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 00777 << E->getSourceRange(); 00778 return; 00779 } 00780 } 00781 00782 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 00783 const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 00784 assert(FT && "FunctionDecl has non-function type?"); 00785 00786 if (isa<FunctionNoProtoType>(FT)) { 00787 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 00788 return; 00789 } 00790 00791 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 00792 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 00793 return; 00794 } 00795 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 00796 if (!MD->isVariadic()) { 00797 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 00798 return; 00799 } 00800 } else if (isa<BlockDecl>(d)) { 00801 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 00802 // caller. 00803 ; 00804 } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 00805 QualType Ty = V->getType(); 00806 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 00807 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 00808 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 00809 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 00810 int m = Ty->isFunctionPointerType() ? 0 : 1; 00811 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 00812 return; 00813 } 00814 } else { 00815 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00816 << Attr.getName() << 6 /*function, method or block */; 00817 return; 00818 } 00819 } else { 00820 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00821 << Attr.getName() << 6 /*function, method or block */; 00822 return; 00823 } 00824 d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos)); 00825 } 00826 00827 static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 00828 // check the attribute arguments. 00829 if (Attr.getNumArgs() != 0) { 00830 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00831 return; 00832 } 00833 00834 if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 00835 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00836 << Attr.getName() << 0 /*function*/; 00837 return; 00838 } 00839 00840 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 00841 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 00842 << Attr.getName() << 0; 00843 return; 00844 } 00845 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 00846 if (MD->getResultType()->isVoidType()) { 00847 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 00848 << Attr.getName() << 1; 00849 return; 00850 } 00851 00852 D->addAttr(::new (S.Context) WarnUnusedResultAttr()); 00853 } 00854 00855 static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 00856 // check the attribute arguments. 00857 if (Attr.getNumArgs() != 0) { 00858 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00859 return; 00860 } 00861 00862 /* weak only applies to non-static declarations */ 00863 if (isStaticVarOrStaticFunciton(D)) { 00864 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 00865 dyn_cast<NamedDecl>(D)->getNameAsString(); 00866 return; 00867 } 00868 00869 // TODO: could also be applied to methods? 00870 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 00871 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00872 << Attr.getName() << 2 /*variable and function*/; 00873 return; 00874 } 00875 00876 D->addAttr(::new (S.Context) WeakAttr()); 00877 } 00878 00879 static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 00880 // check the attribute arguments. 00881 if (Attr.getNumArgs() != 0) { 00882 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00883 return; 00884 } 00885 00886 // weak_import only applies to variable & function declarations. 00887 bool isDef = false; 00888 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 00889 isDef = (!VD->hasExternalStorage() || VD->getInit()); 00890 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 00891 isDef = FD->getBody(); 00892 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 00893 // We ignore weak import on properties and methods 00894 return; 00895 } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) { 00896 // Don't issue the warning for darwin as target; yet, ignore the attribute. 00897 if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin || 00898 !isa<ObjCInterfaceDecl>(D)) 00899 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00900 << Attr.getName() << 2 /*variable and function*/; 00901 return; 00902 } 00903 00904 // Merge should handle any subsequent violations. 00905 if (isDef) { 00906 S.Diag(Attr.getLoc(), 00907 diag::warn_attribute_weak_import_invalid_on_definition) 00908 << "weak_import" << 2 /*variable and function*/; 00909 return; 00910 } 00911 00912 D->addAttr(::new (S.Context) WeakImportAttr()); 00913 } 00914 00915 static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 00916 Sema &S) { 00917 // Attribute has 3 arguments. 00918 if (Attr.getNumArgs() != 3) { 00919 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 00920 return; 00921 } 00922 00923 unsigned WGSize[3]; 00924 for (unsigned i = 0; i < 3; ++i) { 00925 Expr *E = static_cast<Expr *>(Attr.getArg(i)); 00926 llvm::APSInt ArgNum(32); 00927 if (!E->isIntegerConstantExpr(ArgNum, S.Context)) { 00928 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 00929 << "reqd_work_group_size" << E->getSourceRange(); 00930 return; 00931 } 00932 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 00933 } 00934 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], 00935 WGSize[2])); 00936 } 00937 00938 static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 00939 // Attribute has no arguments. 00940 if (Attr.getNumArgs() != 1) { 00941 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 00942 return; 00943 } 00944 00945 // Make sure that there is a string literal as the sections's single 00946 // argument. 00947 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 00948 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 00949 if (!SE) { 00950 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 00951 return; 00952 } 00953 00954 // If the target wants to validate the section specifier, make it happen. 00955 std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 00956 if (!Error.empty()) { 00957 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 00958 << Error; 00959 return; 00960 } 00961 00962 // This attribute cannot be applied to local variables. 00963 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 00964 S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 00965 return; 00966 } 00967 00968 D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString())); 00969 } 00970 00971 00972 static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00973 // check the attribute arguments. 00974 if (Attr.getNumArgs() != 0) { 00975 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00976 return; 00977 } 00978 00979 d->addAttr(::new (S.Context) NoThrowAttr()); 00980 } 00981 00982 static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00983 // check the attribute arguments. 00984 if (Attr.getNumArgs() != 0) { 00985 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00986 return; 00987 } 00988 00989 d->addAttr(::new (S.Context) ConstAttr()); 00990 } 00991 00992 static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 00993 // check the attribute arguments. 00994 if (Attr.getNumArgs() != 0) { 00995 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 00996 return; 00997 } 00998 00999 d->addAttr(::new (S.Context) PureAttr()); 01000 } 01001 01002 static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01003 if (!Attr.getParameterName()) { 01004 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 01005 return; 01006 } 01007 01008 if (Attr.getNumArgs() != 0) { 01009 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 01010 return; 01011 } 01012 01013 VarDecl *VD = dyn_cast<VarDecl>(d); 01014 01015 if (!VD || !VD->hasLocalStorage()) { 01016 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 01017 return; 01018 } 01019 01020 // Look up the function 01021 // FIXME: Lookup probably isn't looking in the right place 01022 // FIXME: The lookup source location should be in the attribute, not the 01023 // start of the attribute. 01024 NamedDecl *CleanupDecl 01025 = S.LookupSingleName(S.TUScope, Attr.getParameterName(), Attr.getLoc(), 01026 Sema::LookupOrdinaryName); 01027 if (!CleanupDecl) { 01028 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 01029 Attr.getParameterName(); 01030 return; 01031 } 01032 01033 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 01034 if (!FD) { 01035 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 01036 Attr.getParameterName(); 01037 return; 01038 } 01039 01040 if (FD->getNumParams() != 1) { 01041 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 01042 Attr.getParameterName(); 01043 return; 01044 } 01045 01046 // We're currently more strict than GCC about what function types we accept. 01047 // If this ever proves to be a problem it should be easy to fix. 01048 QualType Ty = S.Context.getPointerType(VD->getType()); 01049 QualType ParamTy = FD->getParamDecl(0)->getType(); 01050 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 01051 S.Diag(Attr.getLoc(), 01052 diag::err_attribute_cleanup_func_arg_incompatible_type) << 01053 Attr.getParameterName() << ParamTy << Ty; 01054 return; 01055 } 01056 01057 d->addAttr(::new (S.Context) CleanupAttr(FD)); 01058 } 01059 01060 /// Handle __attribute__((format_arg((idx)))) attribute based on 01061 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 01062 static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01063 if (Attr.getNumArgs() != 1) { 01064 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 01065 return; 01066 } 01067 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 01068 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01069 << Attr.getName() << 0 /*function*/; 01070 return; 01071 } 01072 // FIXME: in C++ the implicit 'this' function parameter also counts. this is 01073 // needed in order to be compatible with GCC the index must start with 1. 01074 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 01075 unsigned FirstIdx = 1; 01076 // checks for the 2nd argument 01077 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 01078 llvm::APSInt Idx(32); 01079 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 01080 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 01081 << "format" << 2 << IdxExpr->getSourceRange(); 01082 return; 01083 } 01084 01085 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 01086 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 01087 << "format" << 2 << IdxExpr->getSourceRange(); 01088 return; 01089 } 01090 01091 unsigned ArgIdx = Idx.getZExtValue() - 1; 01092 01093 // make sure the format string is really a string 01094 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 01095 01096 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 01097 if (not_nsstring_type && 01098 !isCFStringType(Ty, S.Context) && 01099 (!Ty->isPointerType() || 01100 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 01101 // FIXME: Should highlight the actual expression that has the wrong type. 01102 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 01103 << (not_nsstring_type ? "a string type" : "an NSString") 01104 << IdxExpr->getSourceRange(); 01105 return; 01106 } 01107 Ty = getFunctionOrMethodResultType(d); 01108 if (!isNSStringType(Ty, S.Context) && 01109 !isCFStringType(Ty, S.Context) && 01110 (!Ty->isPointerType() || 01111 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 01112 // FIXME: Should highlight the actual expression that has the wrong type. 01113 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 01114 << (not_nsstring_type ? "string type" : "NSString") 01115 << IdxExpr->getSourceRange(); 01116 return; 01117 } 01118 01119 d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); 01120 } 01121 01122 enum FormatAttrKind { 01123 CFStringFormat, 01124 NSStringFormat, 01125 StrftimeFormat, 01126 SupportedFormat, 01127 IgnoredFormat, 01128 InvalidFormat 01129 }; 01130 01131 /// getFormatAttrKind - Map from format attribute names to supported format 01132 /// types. 01133 static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 01134 // Check for formats that get handled specially. 01135 if (Format == "NSString") 01136 return NSStringFormat; 01137 if (Format == "CFString") 01138 return CFStringFormat; 01139 if (Format == "strftime") 01140 return StrftimeFormat; 01141 01142 // Otherwise, check for supported formats. 01143 if (Format == "scanf" || Format == "printf" || Format == "printf0" || 01144 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 01145 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 01146 Format == "zcmn_err") 01147 return SupportedFormat; 01148 01149 if (Format == "gcc_diag" || Format == "gcc_cdiag" || 01150 Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 01151 return IgnoredFormat; 01152 01153 return InvalidFormat; 01154 } 01155 01156 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on 01157 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 01158 static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01159 01160 if (!Attr.getParameterName()) { 01161 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 01162 << "format" << 1; 01163 return; 01164 } 01165 01166 if (Attr.getNumArgs() != 2) { 01167 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 01168 return; 01169 } 01170 01171 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 01172 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01173 << Attr.getName() << 0 /*function*/; 01174 return; 01175 } 01176 01177 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 01178 unsigned FirstIdx = 1; 01179 01180 llvm::StringRef Format = Attr.getParameterName()->getName(); 01181 01182 // Normalize the argument, __foo__ becomes foo. 01183 if (Format.startswith("__") && Format.endswith("__")) 01184 Format = Format.substr(2, Format.size() - 4); 01185 01186 // Check for supported formats. 01187 FormatAttrKind Kind = getFormatAttrKind(Format); 01188 01189 if (Kind == IgnoredFormat) 01190 return; 01191 01192 if (Kind == InvalidFormat) { 01193 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 01194 << "format" << Attr.getParameterName()->getName(); 01195 return; 01196 } 01197 01198 // checks for the 2nd argument 01199 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 01200 llvm::APSInt Idx(32); 01201 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 01202 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 01203 << "format" << 2 << IdxExpr->getSourceRange(); 01204 return; 01205 } 01206 01207 // FIXME: We should handle the implicit 'this' parameter in a more generic 01208 // way that can be used for other arguments. 01209 bool HasImplicitThisParam = false; 01210 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 01211 if (MD->isInstance()) { 01212 HasImplicitThisParam = true; 01213 NumArgs++; 01214 } 01215 } 01216 01217 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 01218 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 01219 << "format" << 2 << IdxExpr->getSourceRange(); 01220 return; 01221 } 01222 01223 // FIXME: Do we need to bounds check? 01224 unsigned ArgIdx = Idx.getZExtValue() - 1; 01225 01226 if (HasImplicitThisParam) { 01227 if (ArgIdx == 0) { 01228 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 01229 << "a string type" << IdxExpr->getSourceRange(); 01230 return; 01231 } 01232 ArgIdx--; 01233 } 01234 01235 // make sure the format string is really a string 01236 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 01237 01238 if (Kind == CFStringFormat) { 01239 if (!isCFStringType(Ty, S.Context)) { 01240 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 01241 << "a CFString" << IdxExpr->getSourceRange(); 01242 return; 01243 } 01244 } else if (Kind == NSStringFormat) { 01245 // FIXME: do we need to check if the type is NSString*? What are the 01246 // semantics? 01247 if (!isNSStringType(Ty, S.Context)) { 01248 // FIXME: Should highlight the actual expression that has the wrong type. 01249 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 01250 << "an NSString" << IdxExpr->getSourceRange(); 01251 return; 01252 } 01253 } else if (!Ty->isPointerType() || 01254 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 01255 // FIXME: Should highlight the actual expression that has the wrong type. 01256 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 01257 << "a string type" << IdxExpr->getSourceRange(); 01258 return; 01259 } 01260 01261 // check the 3rd argument 01262 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 01263 llvm::APSInt FirstArg(32); 01264 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 01265 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 01266 << "format" << 3 << FirstArgExpr->getSourceRange(); 01267 return; 01268 } 01269 01270 // check if the function is variadic if the 3rd argument non-zero 01271 if (FirstArg != 0) { 01272 if (isFunctionOrMethodVariadic(d)) { 01273 ++NumArgs; // +1 for ... 01274 } else { 01275 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 01276 return; 01277 } 01278 } 01279 01280 // strftime requires FirstArg to be 0 because it doesn't read from any 01281 // variable the input is just the current time + the format string. 01282 if (Kind == StrftimeFormat) { 01283 if (FirstArg != 0) { 01284 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 01285 << FirstArgExpr->getSourceRange(); 01286 return; 01287 } 01288 // if 0 it disables parameter checking (to use with e.g. va_list) 01289 } else if (FirstArg != 0 && FirstArg != NumArgs) { 01290 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 01291 << "format" << 3 << FirstArgExpr->getSourceRange(); 01292 return; 01293 } 01294 01295 d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(), 01296 FirstArg.getZExtValue())); 01297 } 01298 01299 static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 01300 Sema &S) { 01301 // check the attribute arguments. 01302 if (Attr.getNumArgs() != 0) { 01303 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01304 return; 01305 } 01306 01307 // Try to find the underlying union declaration. 01308 RecordDecl *RD = 0; 01309 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 01310 if (TD && TD->getUnderlyingType()->isUnionType()) 01311 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 01312 else 01313 RD = dyn_cast<RecordDecl>(d); 01314 01315 if (!RD || !RD->isUnion()) { 01316 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01317 << Attr.getName() << 1 /*union*/; 01318 return; 01319 } 01320 01321 if (!RD->isDefinition()) { 01322 S.Diag(Attr.getLoc(), 01323 diag::warn_transparent_union_attribute_not_definition); 01324 return; 01325 } 01326 01327 RecordDecl::field_iterator Field = RD->field_begin(), 01328 FieldEnd = RD->field_end(); 01329 if (Field == FieldEnd) { 01330 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 01331 return; 01332 } 01333 01334 FieldDecl *FirstField = *Field; 01335 QualType FirstType = FirstField->getType(); 01336 if (FirstType->isFloatingType() || FirstType->isVectorType()) { 01337 S.Diag(FirstField->getLocation(), 01338 diag::warn_transparent_union_attribute_floating); 01339 return; 01340 } 01341 01342 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 01343 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 01344 for (; Field != FieldEnd; ++Field) { 01345 QualType FieldType = Field->getType(); 01346 if (S.Context.getTypeSize(FieldType) != FirstSize || 01347 S.Context.getTypeAlign(FieldType) != FirstAlign) { 01348 // Warn if we drop the attribute. 01349 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 01350 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 01351 : S.Context.getTypeAlign(FieldType); 01352 S.Diag(Field->getLocation(), 01353 diag::warn_transparent_union_attribute_field_size_align) 01354 << isSize << Field->getDeclName() << FieldBits; 01355 unsigned FirstBits = isSize? FirstSize : FirstAlign; 01356 S.Diag(FirstField->getLocation(), 01357 diag::note_transparent_union_first_field_size_align) 01358 << isSize << FirstBits; 01359 return; 01360 } 01361 } 01362 01363 RD->addAttr(::new (S.Context) TransparentUnionAttr()); 01364 } 01365 01366 static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01367 // check the attribute arguments. 01368 if (Attr.getNumArgs() != 1) { 01369 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 01370 return; 01371 } 01372 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 01373 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 01374 01375 // Make sure that there is a string literal as the annotation's single 01376 // argument. 01377 if (!SE) { 01378 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 01379 return; 01380 } 01381 d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString())); 01382 } 01383 01384 static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01385 // check the attribute arguments. 01386 if (Attr.getNumArgs() > 1) { 01387 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 01388 return; 01389 } 01390 01391 //FIXME: The C++0x version of this attribute has more limited applicabilty 01392 // than GNU's, and should error out when it is used to specify a 01393 // weaker alignment, rather than being silently ignored. 01394 01395 unsigned Align = 0; 01396 if (Attr.getNumArgs() == 0) { 01397 // FIXME: This should be the target specific maximum alignment. 01398 // (For now we just use 128 bits which is the maximum on X86). 01399 Align = 128; 01400 d->addAttr(::new (S.Context) AlignedAttr(Align)); 01401 return; 01402 } 01403 01404 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 01405 llvm::APSInt Alignment(32); 01406 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 01407 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 01408 << "aligned" << alignmentExpr->getSourceRange(); 01409 return; 01410 } 01411 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 01412 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 01413 << alignmentExpr->getSourceRange(); 01414 return; 01415 } 01416 01417 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 01418 } 01419 01420 /// HandleModeAttr - This attribute modifies the width of a decl with primitive 01421 /// type. 01422 /// 01423 /// Despite what would be logical, the mode attribute is a decl attribute, not a 01424 /// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 01425 /// HImode, not an intermediate pointer. 01426 static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 01427 // This attribute isn't documented, but glibc uses it. It changes 01428 // the width of an int or unsigned int to the specified size. 01429 01430 // Check that there aren't any arguments 01431 if (Attr.getNumArgs() != 0) { 01432 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01433 return; 01434 } 01435 01436 IdentifierInfo *Name = Attr.getParameterName(); 01437 if (!Name) { 01438 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 01439 return; 01440 } 01441 01442 llvm::StringRef Str = Attr.getParameterName()->getName(); 01443 01444 // Normalize the attribute name, __foo__ becomes foo. 01445 if (Str.startswith("__") && Str.endswith("__")) 01446 Str = Str.substr(2, Str.size() - 4); 01447 01448 unsigned DestWidth = 0; 01449 bool IntegerMode = true; 01450 bool ComplexMode = false; 01451 switch (Str.size()) { 01452 case 2: 01453 switch (Str[0]) { 01454 case 'Q': DestWidth = 8; break; 01455 case 'H': DestWidth = 16; break; 01456 case 'S': DestWidth = 32; break; 01457 case 'D': DestWidth = 64; break; 01458 case 'X': DestWidth = 96; break; 01459 case 'T': DestWidth = 128; break; 01460 } 01461 if (Str[1] == 'F') { 01462 IntegerMode = false; 01463 } else if (Str[1] == 'C') { 01464 IntegerMode = false; 01465 ComplexMode = true; 01466 } else if (Str[1] != 'I') { 01467 DestWidth = 0; 01468 } 01469 break; 01470 case 4: 01471 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 01472 // pointer on PIC16 and other embedded platforms. 01473 if (Str == "word") 01474 DestWidth = S.Context.Target.getPointerWidth(0); 01475 else if (Str == "byte") 01476 DestWidth = S.Context.Target.getCharWidth(); 01477 break; 01478 case 7: 01479 if (Str == "pointer") 01480 DestWidth = S.Context.Target.getPointerWidth(0); 01481 break; 01482 } 01483 01484 QualType OldTy; 01485 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 01486 OldTy = TD->getUnderlyingType(); 01487 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 01488 OldTy = VD->getType(); 01489 else { 01490 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 01491 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 01492 return; 01493 } 01494 01495 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 01496 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 01497 else if (IntegerMode) { 01498 if (!OldTy->isIntegralType()) 01499 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 01500 } else if (ComplexMode) { 01501 if (!OldTy->isComplexType()) 01502 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 01503 } else { 01504 if (!OldTy->isFloatingType()) 01505 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 01506 } 01507 01508 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 01509 // and friends, at least with glibc. 01510 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 01511 // width on unusual platforms. 01512 // FIXME: Make sure floating-point mappings are accurate 01513 // FIXME: Support XF and TF types 01514 QualType NewTy; 01515 switch (DestWidth) { 01516 case 0: 01517 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 01518 return; 01519 default: 01520 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 01521 return; 01522 case 8: 01523 if (!IntegerMode) { 01524 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 01525 return; 01526 } 01527 if (OldTy->isSignedIntegerType()) 01528 NewTy = S.Context.SignedCharTy; 01529 else 01530 NewTy = S.Context.UnsignedCharTy; 01531 break; 01532 case 16: 01533 if (!IntegerMode) { 01534 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 01535 return; 01536 } 01537 if (OldTy->isSignedIntegerType()) 01538 NewTy = S.Context.ShortTy; 01539 else 01540 NewTy = S.Context.UnsignedShortTy; 01541 break; 01542 case 32: 01543 if (!IntegerMode) 01544 NewTy = S.Context.FloatTy; 01545 else if (OldTy->isSignedIntegerType()) 01546 NewTy = S.Context.IntTy; 01547 else 01548 NewTy = S.Context.UnsignedIntTy; 01549 break; 01550 case 64: 01551 if (!IntegerMode) 01552 NewTy = S.Context.DoubleTy; 01553 else if (OldTy->isSignedIntegerType()) 01554 if (S.Context.Target.getLongWidth() == 64) 01555 NewTy = S.Context.LongTy; 01556 else 01557 NewTy = S.Context.LongLongTy; 01558 else 01559 if (S.Context.Target.getLongWidth() == 64) 01560 NewTy = S.Context.UnsignedLongTy; 01561 else 01562 NewTy = S.Context.UnsignedLongLongTy; 01563 break; 01564 case 96: 01565 NewTy = S.Context.LongDoubleTy; 01566 break; 01567 case 128: 01568 if (!IntegerMode) { 01569 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 01570 return; 01571 } 01572 if (OldTy->isSignedIntegerType()) 01573 NewTy = S.Context.Int128Ty; 01574 else 01575 NewTy = S.Context.UnsignedInt128Ty; 01576 break; 01577 } 01578 01579 if (ComplexMode) { 01580 NewTy = S.Context.getComplexType(NewTy); 01581 } 01582 01583 // Install the new type. 01584 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 01585 // FIXME: preserve existing source info. 01586 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 01587 } else 01588 cast<ValueDecl>(D)->setType(NewTy); 01589 } 01590 01591 static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01592 // check the attribute arguments. 01593 if (Attr.getNumArgs() > 0) { 01594 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01595 return; 01596 } 01597 01598 if (!isFunctionOrMethod(d)) { 01599 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01600 << Attr.getName() << 0 /*function*/; 01601 return; 01602 } 01603 01604 d->addAttr(::new (S.Context) NoDebugAttr()); 01605 } 01606 01607 static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01608 // check the attribute arguments. 01609 if (Attr.getNumArgs() != 0) { 01610 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01611 return; 01612 } 01613 01614 if (!isa<FunctionDecl>(d)) { 01615 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01616 << Attr.getName() << 0 /*function*/; 01617 return; 01618 } 01619 01620 d->addAttr(::new (S.Context) NoInlineAttr()); 01621 } 01622 01623 static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01624 // check the attribute arguments. 01625 if (Attr.getNumArgs() != 0) { 01626 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01627 return; 01628 } 01629 01630 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 01631 if (Fn == 0) { 01632 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01633 << Attr.getName() << 0 /*function*/; 01634 return; 01635 } 01636 01637 if (!Fn->isInlineSpecified()) { 01638 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 01639 return; 01640 } 01641 01642 d->addAttr(::new (S.Context) GNUInlineAttr()); 01643 } 01644 01645 static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01646 // Diagnostic is emitted elsewhere: here we store the (valid) Attr 01647 // in the Decl node for syntactic reasoning, e.g., pretty-printing. 01648 assert(Attr.isInvalid() == false); 01649 01650 switch (Attr.getKind()) { 01651 case AttributeList::AT_fastcall: 01652 d->addAttr(::new (S.Context) FastCallAttr()); 01653 return; 01654 case AttributeList::AT_stdcall: 01655 d->addAttr(::new (S.Context) StdCallAttr()); 01656 return; 01657 case AttributeList::AT_cdecl: 01658 d->addAttr(::new (S.Context) CDeclAttr()); 01659 return; 01660 default: 01661 llvm_unreachable("unexpected attribute kind"); 01662 return; 01663 } 01664 } 01665 01666 static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01667 // check the attribute arguments. 01668 if (Attr.getNumArgs() != 1) { 01669 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 01670 return; 01671 } 01672 01673 if (!isFunctionOrMethod(d)) { 01674 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01675 << Attr.getName() << 0 /*function*/; 01676 return; 01677 } 01678 01679 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 01680 llvm::APSInt NumParams(32); 01681 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 01682 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 01683 << "regparm" << NumParamsExpr->getSourceRange(); 01684 return; 01685 } 01686 01687 if (S.Context.Target.getRegParmMax() == 0) { 01688 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 01689 << NumParamsExpr->getSourceRange(); 01690 return; 01691 } 01692 01693 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 01694 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 01695 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 01696 return; 01697 } 01698 01699 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 01700 } 01701 01702 static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01703 // check the attribute arguments. 01704 if (Attr.getNumArgs() != 0) { 01705 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01706 return; 01707 } 01708 01709 if (!isa<CXXRecordDecl>(d) 01710 && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 01711 S.Diag(Attr.getLoc(), 01712 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 01713 : diag::warn_attribute_wrong_decl_type) 01714 << Attr.getName() << 7 /*virtual method or class*/; 01715 return; 01716 } 01717 01718 // FIXME: Conform to C++0x redeclaration rules. 01719 01720 if (d->getAttr<FinalAttr>()) { 01721 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 01722 return; 01723 } 01724 01725 d->addAttr(::new (S.Context) FinalAttr()); 01726 } 01727 01728 //===----------------------------------------------------------------------===// 01729 // C++0x member checking attributes 01730 //===----------------------------------------------------------------------===// 01731 01732 static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01733 if (Attr.getNumArgs() != 0) { 01734 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01735 return; 01736 } 01737 01738 if (!isa<CXXRecordDecl>(d)) { 01739 S.Diag(Attr.getLoc(), 01740 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 01741 : diag::warn_attribute_wrong_decl_type) 01742 << Attr.getName() << 9 /*class*/; 01743 return; 01744 } 01745 01746 if (d->getAttr<BaseCheckAttr>()) { 01747 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 01748 return; 01749 } 01750 01751 d->addAttr(::new (S.Context) BaseCheckAttr()); 01752 } 01753 01754 static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01755 if (Attr.getNumArgs() != 0) { 01756 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01757 return; 01758 } 01759 01760 if (!isa<RecordDecl>(d->getDeclContext())) { 01761 // FIXME: It's not the type that's the problem 01762 S.Diag(Attr.getLoc(), 01763 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 01764 : diag::warn_attribute_wrong_decl_type) 01765 << Attr.getName() << 11 /*member*/; 01766 return; 01767 } 01768 01769 // FIXME: Conform to C++0x redeclaration rules. 01770 01771 if (d->getAttr<HidingAttr>()) { 01772 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 01773 return; 01774 } 01775 01776 d->addAttr(::new (S.Context) HidingAttr()); 01777 } 01778 01779 static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 01780 if (Attr.getNumArgs() != 0) { 01781 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01782 return; 01783 } 01784 01785 if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 01786 // FIXME: It's not the type that's the problem 01787 S.Diag(Attr.getLoc(), 01788 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 01789 : diag::warn_attribute_wrong_decl_type) 01790 << Attr.getName() << 10 /*virtual method*/; 01791 return; 01792 } 01793 01794 // FIXME: Conform to C++0x redeclaration rules. 01795 01796 if (d->getAttr<OverrideAttr>()) { 01797 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 01798 return; 01799 } 01800 01801 d->addAttr(::new (S.Context) OverrideAttr()); 01802 } 01803 01804 //===----------------------------------------------------------------------===// 01805 // Checker-specific attribute handlers. 01806 //===----------------------------------------------------------------------===// 01807 01808 static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 01809 Sema &S) { 01810 01811 QualType RetTy; 01812 01813 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 01814 RetTy = MD->getResultType(); 01815 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 01816 RetTy = FD->getResultType(); 01817 else { 01818 SourceLocation L = Attr.getLoc(); 01819 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 01820 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 01821 return; 01822 } 01823 01824 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 01825 || RetTy->getAs<ObjCObjectPointerType>())) { 01826 SourceLocation L = Attr.getLoc(); 01827 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 01828 << SourceRange(L, L) << Attr.getName(); 01829 return; 01830 } 01831 01832 switch (Attr.getKind()) { 01833 default: 01834 assert(0 && "invalid ownership attribute"); 01835 return; 01836 case AttributeList::AT_cf_returns_not_retained: 01837 d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr()); 01838 return; 01839 case AttributeList::AT_ns_returns_not_retained: 01840 d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr()); 01841 return; 01842 case AttributeList::AT_cf_returns_retained: 01843 d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 01844 return; 01845 case AttributeList::AT_ns_returns_retained: 01846 d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 01847 return; 01848 }; 01849 } 01850 01851 static bool isKnownDeclSpecAttr(const AttributeList &Attr) { 01852 return Attr.getKind() == AttributeList::AT_dllimport || 01853 Attr.getKind() == AttributeList::AT_dllexport; 01854 } 01855 01856 //===----------------------------------------------------------------------===// 01857 // Top Level Sema Entry Points 01858 //===----------------------------------------------------------------------===// 01859 01860 /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 01861 /// the attribute applies to decls. If the attribute is a type attribute, just 01862 /// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 01863 /// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 01864 static void ProcessDeclAttribute(Scope *scope, Decl *D, 01865 const AttributeList &Attr, Sema &S) { 01866 if (Attr.isInvalid()) 01867 return; 01868 01869 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 01870 // FIXME: Try to deal with other __declspec attributes! 01871 return; 01872 switch (Attr.getKind()) { 01873 case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 01874 case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 01875 case AttributeList::AT_address_space: 01876 case AttributeList::AT_objc_gc: 01877 case AttributeList::AT_vector_size: 01878 // Ignore these, these are type attributes, handled by 01879 // ProcessTypeAttributes. 01880 break; 01881 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 01882 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 01883 case AttributeList::AT_always_inline: 01884 HandleAlwaysInlineAttr (D, Attr, S); break; 01885 case AttributeList::AT_analyzer_noreturn: 01886 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 01887 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 01888 case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 01889 case AttributeList::AT_carries_dependency: 01890 HandleDependencyAttr (D, Attr, S); break; 01891 case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 01892 case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 01893 case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 01894 case AttributeList::AT_ext_vector_type: 01895 HandleExtVectorTypeAttr(scope, D, Attr, S); 01896 break; 01897 case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 01898 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 01899 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 01900 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 01901 case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 01902 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 01903 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 01904 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 01905 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 01906 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 01907 case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 01908 01909 // Checker-specific. 01910 case AttributeList::AT_ns_returns_not_retained: 01911 case AttributeList::AT_cf_returns_not_retained: 01912 case AttributeList::AT_ns_returns_retained: 01913 case AttributeList::AT_cf_returns_retained: 01914 HandleNSReturnsRetainedAttr(D, Attr, S); break; 01915 01916 case AttributeList::AT_reqd_wg_size: 01917 HandleReqdWorkGroupSize(D, Attr, S); break; 01918 01919 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 01920 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 01921 case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 01922 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 01923 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 01924 case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 01925 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 01926 break; 01927 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 01928 case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 01929 case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 01930 case AttributeList::AT_transparent_union: 01931 HandleTransparentUnionAttr(D, Attr, S); 01932 break; 01933 case AttributeList::AT_objc_exception: 01934 HandleObjCExceptionAttr(D, Attr, S); 01935 break; 01936 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 01937 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 01938 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 01939 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 01940 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 01941 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 01942 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 01943 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 01944 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 01945 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 01946 case AttributeList::IgnoredAttribute: 01947 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 01948 // Just ignore 01949 break; 01950 case AttributeList::AT_stdcall: 01951 case AttributeList::AT_cdecl: 01952 case AttributeList::AT_fastcall: 01953 HandleCallConvAttr(D, Attr, S); 01954 break; 01955 default: 01956 // Ask target about the attribute. 01957 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 01958 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 01959 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 01960 break; 01961 } 01962 } 01963 01964 /// ProcessDeclAttributeList - Apply all the decl attributes in the specified 01965 /// attribute list to the specified decl, ignoring any type attributes. 01966 void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 01967 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 01968 ProcessDeclAttribute(S, D, *l, *this); 01969 } 01970 01971 // GCC accepts 01972 // static int a9 __attribute__((weakref)); 01973 // but that looks really pointless. We reject it. 01974 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 01975 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 01976 dyn_cast<NamedDecl>(D)->getNameAsString(); 01977 return; 01978 } 01979 } 01980 01981 /// DeclClonePragmaWeak - clone existing decl (maybe definition), 01982 /// #pragma weak needs a non-definition decl and source may not have one 01983 NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 01984 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 01985 NamedDecl *NewD = 0; 01986 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 01987 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 01988 FD->getLocation(), DeclarationName(II), 01989 FD->getType(), FD->getTypeSourceInfo()); 01990 if (FD->getQualifier()) { 01991 FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 01992 NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 01993 } 01994 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 01995 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 01996 VD->getLocation(), II, 01997 VD->getType(), VD->getTypeSourceInfo(), 01998 VD->getStorageClass(), 01999 VD->getStorageClassAsWritten()); 02000 if (VD->getQualifier()) { 02001 VarDecl *NewVD = cast<VarDecl>(NewD); 02002 NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 02003 } 02004 } 02005 return NewD; 02006 } 02007 02008 /// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 02009 /// applied to it, possibly with an alias. 02010 void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 02011 if (W.getUsed()) return; // only do this once 02012 W.setUsed(true); 02013 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 02014 IdentifierInfo *NDId = ND->getIdentifier(); 02015 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 02016 NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName())); 02017 NewD->addAttr(::new (Context) WeakAttr()); 02018 WeakTopLevelDecl.push_back(NewD); 02019 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 02020 // to insert Decl at TU scope, sorry. 02021 DeclContext *SavedContext = CurContext; 02022 CurContext = Context.getTranslationUnitDecl(); 02023 PushOnScopeChains(NewD, S); 02024 CurContext = SavedContext; 02025 } else { // just add weak to existing 02026 ND->addAttr(::new (Context) WeakAttr()); 02027 } 02028 } 02029 02030 /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 02031 /// it, apply them to D. This is a bit tricky because PD can have attributes 02032 /// specified in many different places, and we need to find and apply them all. 02033 void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 02034 // Handle #pragma weak 02035 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 02036 if (ND->hasLinkage()) { 02037 WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 02038 if (W != WeakInfo()) { 02039 // Identifier referenced by #pragma weak before it was declared 02040 DeclApplyPragmaWeak(S, ND, W); 02041 WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 02042 } 02043 } 02044 } 02045 02046 // Apply decl attributes from the DeclSpec if present. 02047 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 02048 ProcessDeclAttributeList(S, D, Attrs); 02049 02050 // Walk the declarator structure, applying decl attributes that were in a type 02051 // position to the decl itself. This handles cases like: 02052 // int *__attr__(x)** D; 02053 // when X is a decl attribute. 02054 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 02055 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 02056 ProcessDeclAttributeList(S, D, Attrs); 02057 02058 // Finally, apply any attributes on the decl itself. 02059 if (const AttributeList *Attrs = PD.getAttributes()) 02060 ProcessDeclAttributeList(S, D, Attrs); 02061 } 02062 02063 /// PushParsingDeclaration - Enter a new "scope" of deprecation 02064 /// warnings. 02065 /// 02066 /// The state token we use is the start index of this scope 02067 /// on the warning stack. 02068 Action::ParsingDeclStackState Sema::PushParsingDeclaration() { 02069 ParsingDeclDepth++; 02070 return (ParsingDeclStackState) DelayedDiagnostics.size(); 02071 } 02072 02073 void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) { 02074 assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 02075 ParsingDeclDepth--; 02076 02077 if (DelayedDiagnostics.empty()) 02078 return; 02079 02080 unsigned SavedIndex = (unsigned) S; 02081 assert(SavedIndex <= DelayedDiagnostics.size() && 02082 "saved index is out of bounds"); 02083 02084 unsigned E = DelayedDiagnostics.size(); 02085 02086 // We only want to actually emit delayed diagnostics when we 02087 // successfully parsed a decl. 02088 Decl *D = Ctx ? Ctx.getAs<Decl>() : 0; 02089 if (D) { 02090 // We really do want to start with 0 here. We get one push for a 02091 // decl spec and another for each declarator; in a decl group like: 02092 // deprecated_typedef foo, *bar, baz(); 02093 // only the declarator pops will be passed decls. This is correct; 02094 // we really do need to consider delayed diagnostics from the decl spec 02095 // for each of the different declarations. 02096 for (unsigned I = 0; I != E; ++I) { 02097 if (DelayedDiagnostics[I].Triggered) 02098 continue; 02099 02100 switch (DelayedDiagnostics[I].Kind) { 02101 case DelayedDiagnostic::Deprecation: 02102 HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 02103 break; 02104 02105 case DelayedDiagnostic::Access: 02106 HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 02107 break; 02108 } 02109 } 02110 } 02111 02112 // Destroy all the delayed diagnostics we're about to pop off. 02113 for (unsigned I = SavedIndex; I != E; ++I) 02114 DelayedDiagnostics[I].destroy(); 02115 02116 DelayedDiagnostics.set_size(SavedIndex); 02117 } 02118 02119 static bool isDeclDeprecated(Decl *D) { 02120 do { 02121 if (D->hasAttr<DeprecatedAttr>()) 02122 return true; 02123 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 02124 return false; 02125 } 02126 02127 void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD, 02128 Decl *Ctx) { 02129 if (isDeclDeprecated(Ctx)) 02130 return; 02131 02132 DD.Triggered = true; 02133 Diag(DD.Loc, diag::warn_deprecated) 02134 << DD.DeprecationData.Decl->getDeclName(); 02135 } 02136 02137 void Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) { 02138 // Delay if we're currently parsing a declaration. 02139 if (ParsingDeclDepth) { 02140 DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D)); 02141 return; 02142 } 02143 02144 // Otherwise, don't warn if our current context is deprecated. 02145 if (isDeclDeprecated(cast<Decl>(CurContext))) 02146 return; 02147 02148 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 02149 }