SemaDeclAttr.cpp revision dd0e490c24aeade2c59ca4cae171199f6af9f02e
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// 26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// The LLVM Compiler Infrastructure 46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source 66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details. 76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file implements decl-related attribute processing. 116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "Sema.h" 1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h" 166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h" 17acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 18acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 19fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 2012bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h" 21797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h" 226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 27e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 28a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic const FunctionType *getFunctionType(const Decl *d, 29a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek bool blocksToo = true) { 306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 31a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek if (const ValueDecl *decl = dyn_cast<ValueDecl>(d)) 326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 33a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d)) 346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 35a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 39bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 416217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<PointerType>()->getPointeeType(); 42755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian else if (blocksToo && Ty->isBlockPointerType()) 436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 44d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 45183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall return Ty->getAs<FunctionType>(); 466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 483568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 493568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 503568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 51d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function 52a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable). 53a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunction(const Decl *d) { 54a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek return getFunctionType(d, false) != NULL; 55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek} 56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek 57a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function 58d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 59d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 60a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethod(const Decl *d) { 61a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek return isFunction(d)|| isa<ObjCMethodDecl>(d); 62d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 633568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 64620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function 65620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C 66620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block. 67a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodOrBlock(const Decl *d) { 68620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (isFunctionOrMethod(d)) 69620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return true; 70620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian // check for block is more involved. 71620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 72620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian QualType Ty = V->getType(); 73620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return Ty->isBlockPointerType(); 74620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 75d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return isa<BlockDecl>(d); 76620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian} 77620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 78d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 79d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 80620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) { 82620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 8372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 84620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else { 85d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 86d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 87d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 893568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 90d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 91d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 92d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 93a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) { 9489951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 9572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 96d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 97d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getNumParams(); 9889951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_size(); 993568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1003568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 101a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) { 10289951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 10372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 104d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 105d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getParamDecl(Idx)->getType(); 106bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10789951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 1083568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1093568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 110a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) { 1115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 1125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<FunctionProtoType>(FnTy)->getResultType(); 1135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<ObjCMethodDecl>(d)->getResultType(); 1145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 1155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 116a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) { 117d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 11872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1193568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 120d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 121db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek return BD->isVariadic(); 122d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian else { 1233568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 1243568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1253568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1263568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 1276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 128183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 129b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 131bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 132506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 133506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall if (!Cls) 1346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 135bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 136506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall IdentifierInfo* ClsName = Cls->getIdentifier(); 137bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 143085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 1446217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 145085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 146085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 147085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1486217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 149085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 150085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 152085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 153465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (RD->getTagKind() != TTK_Struct) 154085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 155085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 156085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 157085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 158085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 159e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 160e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 161e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 162e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 1643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 1653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 1663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 1689cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor const AttributeList &Attr, Sema &S) { 169545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 170545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 171803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 172545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 174bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1769cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 1789cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 1809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 181f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 182f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 183f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 184f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); 1859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 1869cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 1879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getNumArgs() != 1) { 1889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 1909cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } 1919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 1959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 1969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc()); 1979cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 198ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 199a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 200bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2019cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 2029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 2036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 206803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 208545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 2093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 212bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 214a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson TD->addAttr(::new (S.Context) PackedAttr); 2156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 219803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 220fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 22108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 223a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson FD->addAttr(::new (S.Context) PackedAttr); 2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 2253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 22863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) { 22996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 23096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 2313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 23296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 23396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 234bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 23663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 23763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 23863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek d->addAttr(::new (S.Context) IBActionAttr()); 23963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 24063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 24163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 24263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName(); 24363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 24463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 24563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) { 24663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 24763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (Attr.getNumArgs() > 0) { 24863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 24963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 25063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 25163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 25263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBOutlet attributes only apply to instance variables of 253efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek // Objective-C classes. 254efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) { 25563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek d->addAttr(::new (S.Context) IBOutletAttr()); 25663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 257efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek } 25863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 25963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 26096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 26196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 262857e918a8a40deb128840308a318bf623d68295fTed Kremenekstatic void HandleIBOutletCollection(Decl *d, const AttributeList &Attr, 263857e918a8a40deb128840308a318bf623d68295fTed Kremenek Sema &S) { 264857e918a8a40deb128840308a318bf623d68295fTed Kremenek 265857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The iboutletcollection attribute can have zero or one arguments. 266857e918a8a40deb128840308a318bf623d68295fTed Kremenek if (Attr.getNumArgs() > 1) { 267857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 268857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 269857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 270857e918a8a40deb128840308a318bf623d68295fTed Kremenek 271857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The IBOutletCollection attributes only apply to instance variables of 272857e918a8a40deb128840308a318bf623d68295fTed Kremenek // Objective-C classes. 273857e918a8a40deb128840308a318bf623d68295fTed Kremenek if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) { 274857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 275857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 276857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 277857e918a8a40deb128840308a318bf623d68295fTed Kremenek 278857e918a8a40deb128840308a318bf623d68295fTed Kremenek // FIXME: Eventually accept the type argument. 279857e918a8a40deb128840308a318bf623d68295fTed Kremenek d->addAttr(::new (S.Context) IBOutletCollectionAttr()); 280857e918a8a40deb128840308a318bf623d68295fTed Kremenek} 281857e918a8a40deb128840308a318bf623d68295fTed Kremenek 282eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 283bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 284bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 285d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 286fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2875dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 288eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 289eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 290bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 291d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 292eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 293eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 294eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 295bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 298bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 299bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 300eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 301f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek Expr *Ex = static_cast<Expr *>(*I); 302eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 303ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Ex->isTypeDependent() || Ex->isValueDependent() || 304ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 305fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 306fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 307eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 308eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 309bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 310eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 311bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 312eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 313fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 31430bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 315eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 316eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 317bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 318465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 319eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 320eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 321bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump QualType T = getFunctionOrMethodArgType(d, x); 322dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 324fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 325fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 3267fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 327eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 328bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 331bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 332bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 333bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 3347fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 33546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 33646bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, I); 337dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 338d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 33946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 340bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3417fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 3427fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 3437fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 3447fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek } 345eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 3467fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3477fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 3487fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 349dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 3505961611172f1c210fbbaa55b3c692e13b1fc7be4Ted Kremenek d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size)); 351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 352eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 353dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekstatic void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) { 354dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This attribute must be applied to a function declaration. 355dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The first argument to the attribute must be a string, 356dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // the name of the resource, for example "malloc". 357dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The following arguments must be argument indexes, the arguments must be 358dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // of integer type for Returns, otherwise of pointer type. 359dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The difference between Holds and Takes is that a pointer may still be used 360dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // after being held. free() should be __attribute((ownership_takes)), whereas a list 361dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // append function may well be __attribute((ownership_holds)). 362dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 363dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!AL.getParameterName()) { 364dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 365dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << 1; 366dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 367dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 368dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Figure out our Kind, and check arguments while we're at it. 369dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipAttr::OwnershipKind K = OwnershipAttr::None; 370dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getName()->getName().equals("ownership_takes")) { 371dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek K = OwnershipAttr::Takes; 372dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 373dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 374dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 375dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 376dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } else if (AL.getName()->getName().equals("ownership_holds")) { 377dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek K = OwnershipAttr::Holds; 378dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 379dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 380dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 381dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 382dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } else if (AL.getName()->getName().equals("ownership_returns")) { 383dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek K = OwnershipAttr::Returns; 384dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 385dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 386dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getNumArgs() + 1; 387dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 388dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 389dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 390dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This should never happen given how we are called. 391dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (K == OwnershipAttr::None) { 392dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 393dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 394dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 395dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!isFunction(d) || !hasFunctionProto(d)) { 396dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName() 397dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << 0 /*function*/; 398dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 399dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 400dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 401dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned NumArgs = getFunctionOrMethodNumArgs(d); 402dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 403dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::StringRef Module = AL.getParameterName()->getName(); 404dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 405dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Normalize the argument, __foo__ becomes foo. 406dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (Module.startswith("__") && Module.endswith("__")) 407dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module = Module.substr(2, Module.size() - 4); 408dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 409dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::SmallVector<unsigned, 10> OwnershipArgs; 410dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 411dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; ++I) { 412dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 413dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Expr *IdxExpr = static_cast<Expr *>(*I); 414dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 415dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 416dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 417dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 418dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << IdxExpr->getSourceRange(); 419dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 420dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 421dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 422dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 423dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 424dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x > NumArgs || x < 1) { 425dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 426dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 427dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 428dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 429dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek --x; 430dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 431dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case OwnershipAttr::Takes: 432dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case OwnershipAttr::Holds: { 433dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument a pointer type? 434dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek QualType T = getFunctionOrMethodArgType(d, x); 435dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 436dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // FIXME: Should also highlight argument in decl. 437dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 438dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 439dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "pointer" 440dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 441dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 442dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 443dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 444dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 445dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case OwnershipAttr::Returns: { 446dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 447dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument an integer type? 448dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Expr *IdxExpr = static_cast<Expr *>(AL.getArg(0)); 449dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 450dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 451dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 452dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 453dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "ownership_returns" << "integer" 454dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 455dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 456dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 457dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 458dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 459dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 460dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Should never happen, here to silence a warning. 461dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek default: { 462dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 463dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 464dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } // switch 465dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 466dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Check we don't have a conflict with another ownership attribute. 467dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (d->hasAttrs()) { 468dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek for (const Attr *attr = d->getAttrs(); attr; attr = attr->getNext()) { 469dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (const OwnershipAttr* Att = dyn_cast<OwnershipAttr>(attr)) { 470dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Two ownership attributes of the same kind can't conflict, 471dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // except returns attributes. 472dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (K == OwnershipAttr::Returns || Att->getKind() != K) { 473dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek for (const unsigned *I = Att->begin(), *E = Att->end(); I != E; ++I) { 474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x == *I) { 475dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 476dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << "ownership_*"; 477dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 478dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 480dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 481dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 482dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 483dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipArgs.push_back(x); 484dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 485dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 486dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned* start = OwnershipArgs.data(); 487dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned size = OwnershipArgs.size(); 488dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 489dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 490dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case OwnershipAttr::Takes: { 491dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (OwnershipArgs.empty()) { 492dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 493dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 494dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 495dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek d->addAttr(::new (S.Context) OwnershipTakesAttr(S.Context, start, size, 496dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module)); 497dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 498dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 499dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case OwnershipAttr::Holds: { 500dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (OwnershipArgs.empty()) { 501dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 502dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 503dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 504dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek d->addAttr(::new (S.Context) OwnershipHoldsAttr(S.Context, start, size, 505dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module)); 506dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 507dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 508dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case OwnershipAttr::Returns: { 509dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek d->addAttr(::new (S.Context) OwnershipReturnsAttr(S.Context, start, size, 510dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module)); 511dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 512dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 513dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek default: 514dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 515dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 516dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek} 517dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 51811e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic bool isStaticVarOrStaticFunciton(Decl *D) { 51911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (VarDecl *VD = dyn_cast<VarDecl>(D)) 52011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return VD->getStorageClass() == VarDecl::Static; 52111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 52211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return FD->getStorageClass() == FunctionDecl::Static; 52311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return false; 52411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 52511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 52611e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) { 52711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Check the attribute arguments. 52811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() > 1) { 52911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 53011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 53111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 53211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 53311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc rejects 53411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // class c { 53511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 53611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int b() __attribute__((weakref ("f3"))); 53711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // }; 53811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // and ignores the attributes of 53911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // void f(void) { 54011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 54111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // } 54211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // we reject them 54311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (const DeclContext *Ctx = d->getDeclContext()) { 54411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Ctx = Ctx->getLookupContext(); 54511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (!isa<TranslationUnitDecl>(Ctx) && !isa<NamespaceDecl>(Ctx) ) { 54611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 547dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(d)->getNameAsString(); 54811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 54911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 55011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 55111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 55211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // The GCC manual says 55311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 55411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // At present, a declaration to which `weakref' is attached can only 55511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // be `static'. 55611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 55711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // It also says 55811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 55911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Without a TARGET, 56011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // given as an argument to `weakref' or to `alias', `weakref' is 56111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // equivalent to `weak'. 56211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 56311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc 4.4.1 will accept 56411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weakref)); 56511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // as 56611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weak)); 56711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // This looks like a bug in gcc. We reject that for now. We should revisit 56811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // it if this behaviour is actually used. 56911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 57011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (!isStaticVarOrStaticFunciton(d)) { 57111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) << 57211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola dyn_cast<NamedDecl>(d)->getNameAsString(); 57311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 57411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 57511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 57611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC rejects 57711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static ((alias ("y"), weakref)). 57811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Should we? How to check that weakref is before or after alias? 57911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 58011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() == 1) { 58111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 58211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Arg = Arg->IgnoreParenCasts(); 58311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 58411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 58511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Str == 0 || Str->isWide()) { 58611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 58711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola << "weakref" << 1; 58811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 58911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 59011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC will accept anything as the argument of weakref. Should we 59111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // check for an existing decl? 59211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString())); 59311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 59411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 59511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola d->addAttr(::new (S.Context) WeakRefAttr()); 59611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 59711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 598803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 600545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 6013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 6026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 604bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 605545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 608bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 610fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 6113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 6126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 614bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 616bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6173d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString())); 6186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 620bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 621af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar Sema &S) { 622af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar // check the attribute arguments. 623af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar if (Attr.getNumArgs() != 0) { 6243c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 625af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 626af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 6275bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 628c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 6295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 6305dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 6315bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 6325bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 633bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 63440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AlwaysInlineAttr()); 635af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 636af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 63776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 63876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn // check the attribute arguments. 63976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn if (Attr.getNumArgs() != 0) { 64076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 64176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 64276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6442cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 6451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 6462cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 6472cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek d->addAttr(::new (S.Context) MallocAttr()); 6482cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 6492cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 650fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 651fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 6522cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 65376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 65476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 655b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 656e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Sema &S) { 6576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 658545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 659e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 660b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return false; 6616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 662d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 66319c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 66419c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump ValueDecl *VD = dyn_cast<ValueDecl>(d); 6653ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 6663ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 667e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), 668e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 669e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara : diag::warn_attribute_wrong_decl_type) 670e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara << Attr.getName() << 0 /*function*/; 67119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump return false; 67219c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 6736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 674bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 675b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return true; 676b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 677b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 678b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 679e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */ 680e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara assert(Attr.isInvalid() == false); 681e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara d->addAttr(::new (S.Context) NoReturnAttr()); 682b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 683b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 684b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 685b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek Sema &S) { 686e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara if (HandleCommonNoReturnAttr(d, Attr, S)) 68740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 6886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 690bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 691bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 692bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 69304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall << Attr.getName() << 8 /*function, method, or parameter*/; 694bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 695bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 696bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 697bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 698bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 69973798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 70073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 70173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 7023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 70373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 70473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 705bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 706aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) && 707aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall !isa<TypeDecl>(d)) { 708fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7095dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 71073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 71173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 712bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 71340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UnusedAttr()); 71473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 71573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 716b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 717b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 718b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (Attr.getNumArgs() != 0) { 719b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 720b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 721b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 722bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 723b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 724186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 725b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 726b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 727b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 728b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } else if (!isFunctionOrMethod(d)) { 729b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7305dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 731b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 732b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 733bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 73440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UsedAttr()); 735b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 736b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 7373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 7393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 740fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 741fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 7423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 743bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 7443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 7453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 7463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 7473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 7483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 749ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 750ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 751fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 7523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 7533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 7543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 7553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 7563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 757bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 758c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 759fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7605dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 7613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 7623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 7633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 76440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) ConstructorAttr(priority)); 7653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 7663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 7673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 7693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 770fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 771fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 7723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 773bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 7743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 7753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 7763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 7773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 7783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 779ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 780ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 781fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 7823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 7833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 7843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 7853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 7863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 787bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 7886782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 789fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7905dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 7913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 7923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 7933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 79440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) DestructorAttr(priority)); 7953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 7963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 797803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 799545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 803bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 80440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) DeprecatedAttr()); 8056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 807bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 808bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian // check the attribute arguments. 809bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian if (Attr.getNumArgs() != 0) { 810bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 811bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 812bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 813bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 81440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UnavailableAttr()); 815bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 816bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 817803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 8186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 819545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 8203c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 8216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 823bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 824545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 8256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 8266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 827bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 8286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 829fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 8303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 8316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 833bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 834c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer llvm::StringRef TypeStr = Str->getString(); 8356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 836bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 837c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 8386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 839c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 8406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 841c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 8426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 843c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "protected") 8446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 8456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 84608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 8476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 849bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 85040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) VisibilityAttr(type)); 8516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8530db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 8540db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner Sema &S) { 8550db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (Attr.getNumArgs() != 0) { 8560db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8570db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 8580db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 859bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 8600db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 8610db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 8620db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 8630db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 8640db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 865bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 86640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCExceptionAttr()); 8670db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 8680db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 8690db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 870fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 8712b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 872fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 873fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 8740db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 875fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 876fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 8776217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 878fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 879fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 880fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 881fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 88240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 883fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 884fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 885bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 886f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 887f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 8882b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 889f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 890f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 891f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 892f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 893f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 894f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 895f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 896f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 89740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) OverloadableAttr()); 898f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 899f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 9009eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 901bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 902fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 9033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 9049eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 9059eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 906bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 9079eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 9083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 9099eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 9109eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 911bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 9129eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff BlocksAttr::BlocksAttrTypes type; 91392e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 9149eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 9159eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 916fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 9173c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 9189eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 9199eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 920bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 92140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) BlocksAttr(type)); 9229eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 9239eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 924770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 925770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 926770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 927fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 928fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0, 1 or 2"; 929770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 930bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 931bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 932770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 933770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 934770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(0)); 935770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 936ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 937ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 938fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 9393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 940770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 941770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 942770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 943bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 944770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 945fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 946fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 947770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 948770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 949770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 950770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 951770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 952770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 953770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(1)); 954770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 955ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 956ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 957fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 9583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 959770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 960770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 961770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 962bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 963770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 964770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 965770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 966fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 967fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 968770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 969770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 970770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 971770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 972770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 973183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 974897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner assert(FT && "FunctionDecl has non-function type?"); 975bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 976897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 977897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 978897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 979897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 980bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 981897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 9823bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 983770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 984bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 985770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 986770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 9873bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 988770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 9892f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 9902f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (isa<BlockDecl>(d)) { 991bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 992bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // caller. 9932f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian ; 9942f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 9952f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 996daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 997bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 998183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 9992f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 10003bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 10013bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 10022f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 10032f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1004ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 10052f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1006ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 10072f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 10082f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1009770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 1010fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1011ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 1012770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1013770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 101440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos)); 1015770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 1016770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1017026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 1018026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 1019026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (Attr.getNumArgs() != 0) { 1020026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1021026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1022026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1023026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1024f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1025026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 10265dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1027026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1028026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1029bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1030f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1031f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1032f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 0; 1033f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 1034f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 1035f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1036f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (MD->getResultType()->isVoidType()) { 1037f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1038f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 1; 1039f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian return; 1040f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian } 1041f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian 1042d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes D->addAttr(::new (S.Context) WarnUnusedResultAttr()); 1043026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 1044026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1045026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 10466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1047545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 10483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 10496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10516e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 1052f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian /* weak only applies to non-static declarations */ 105311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (isStaticVarOrStaticFunciton(D)) { 1054f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 1055f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian dyn_cast<NamedDecl>(D)->getNameAsString(); 1056f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 1057f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 1058f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 10596e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // TODO: could also be applied to methods? 10606e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 10616e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 10625dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 10636e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 10646e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 1065bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 106640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakAttr()); 10676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 10686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10696e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 10706e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 10716e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (Attr.getNumArgs() != 0) { 10726e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 10736e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 1074bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 10756e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 10766e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 10776e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 10786e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 10796e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar isDef = (!VD->hasExternalStorage() || VD->getInit()); 10806e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 108106a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis isDef = FD->hasBody(); 1082d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 1083d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian // We ignore weak import on properties and methods 10841c90f4dc686ab872013544664c797604a309c563Mike Stump return; 10855f8f8571c52dbf12fdefb15d2fedbcccb212c15cFariborz Jahanian } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) { 1086c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian // Don't issue the warning for darwin as target; yet, ignore the attribute. 10873be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin || 1088c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian !isa<ObjCInterfaceDecl>(D)) 1089c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 10903be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian << Attr.getName() << 2 /*variable and function*/; 10913be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian return; 10926e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 10936e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 10946e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // Merge should handle any subsequent violations. 10956e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (isDef) { 1096bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 10976e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar diag::warn_attribute_weak_import_invalid_on_definition) 10986e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar << "weak_import" << 2 /*variable and function*/; 10996e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 11006e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 11016e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 110240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakImportAttr()); 11036e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 11046e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 11056f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 11066f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Sema &S) { 11076f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 11086f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman if (Attr.getNumArgs() != 3) { 11092b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 11106f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 11116f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 11126f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 11136f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 11146f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 11156f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Expr *E = static_cast<Expr *>(Attr.getArg(i)); 11166f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 1117ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1118ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(ArgNum, S.Context)) { 11196f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 11206f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 11216f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 11226f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 11236f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 11246f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 112540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], 11266f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 11276f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 11286f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 1129026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 113017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 113117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (Attr.getNumArgs() != 1) { 113217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 113317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 113417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 113517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 113617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 113717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 1138797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1139797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 114017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 1141797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 114217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 114317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 11441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1145797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 1146bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 1147a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 1148a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1149a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 1150797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 1151797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 11521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1153a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 1154a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 1155a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 1156a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 1157a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 1158a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner 11593d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString())); 116017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 116117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 11626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1163803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 11646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1165545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 11663c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 11676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1169bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 117040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NoThrowAttr()); 11716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 11726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1173232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1174232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1175232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 11763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1177232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1178232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1179bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 118040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) ConstAttr()); 1181232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1182232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1183232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1184232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1185232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 11863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1187232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1188232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1189bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 119040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) PureAttr()); 1191232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1192232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1193f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1194bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1195f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1196f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1197f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1198bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1199f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 1200f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1201f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1202f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1203bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1204f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson VarDecl *VD = dyn_cast<VarDecl>(d); 1205bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1206f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 1207f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1208f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1209f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1210bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1211f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 1212c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: Lookup probably isn't looking in the right place 1213c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: The lookup source location should be in the attribute, not the 1214c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // start of the attribute. 1215f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 1216c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor = S.LookupSingleName(S.TUScope, Attr.getParameterName(), Attr.getLoc(), 1217f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall Sema::LookupOrdinaryName); 1218f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 121989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1220f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1221f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1222f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1223bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1224f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1225f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 122689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1227f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1228f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1229f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1230f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1231f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 123289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1233f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1234f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1235f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1236bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 123789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 123889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 123989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 124089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 1241d5e3e8ec50d6ea481b3bc841dcbe853175d05122Eli Friedman if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1242bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 124389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 124489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 124589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 124689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 1247bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 124840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) CleanupAttr(FD)); 1249f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 1250f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1251bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 1252bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1253bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 12545b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Attr.getNumArgs() != 1) { 12555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 12565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 12575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 12585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 12595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 12605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << Attr.getName() << 0 /*function*/; 12615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 12625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1263bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1264bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // needed in order to be compatible with GCC the index must start with 1. 12655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned NumArgs = getFunctionOrMethodNumArgs(d); 12665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 12675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 12685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 12695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 1270ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1271ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 12725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 12735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 12745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 12755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1276bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 12785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 12795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 12805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 12815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1282bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12835b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 1284bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 12865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1287bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12885b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 12895b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 12905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 12915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 12926217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 12935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 12945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1295bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 12965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 12975b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1298bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 12995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Ty = getFunctionOrMethodResultType(d); 13005b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 13015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 13025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 13036217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 13045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 13055b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1306bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 13075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 13085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1309bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1310bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 131140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); 13125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 13135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 13142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 13152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 13162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 13172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 13182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 13193c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner IgnoredFormat, 13202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 13212b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 13222b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 13232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 13242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 13252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 13262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for formats that get handled specially. 13272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "NSString") 13282b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return NSStringFormat; 13292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "CFString") 13302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return CFStringFormat; 13312b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "strftime") 13322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return StrftimeFormat; 13332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 13342b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Otherwise, check for supported formats. 13352b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "scanf" || Format == "printf" || Format == "printf0" || 13362b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 13372b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 13382b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "zcmn_err") 13392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return SupportedFormat; 13402b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1341bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands if (Format == "gcc_diag" || Format == "gcc_cdiag" || 1342bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 13433c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return IgnoredFormat; 13443c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 13452b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return InvalidFormat; 13462b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 13472b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1348521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on 1349521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 1350521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 1351521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Sema &S) { 1352521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (!S.getLangOptions().CPlusPlus) { 1353521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1354521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1355521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1356521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 1357b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) { 1358b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1359b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 1360b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 1361b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 1362b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian QualType T = dyn_cast<VarDecl>(d)->getType(); 1363b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (S.Context.getAsArrayType(T)) 1364b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian T = S.Context.getBaseElementType(T); 1365b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!T->getAs<RecordType>()) { 1366b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1367b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 1368b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 1369b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 1370b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 1371521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (Attr.getNumArgs() != 1) { 1372521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1373521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1374521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1375521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1376521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Expr *priorityExpr = static_cast<Expr *>(Attr.getArg(0)); 1377b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 1378521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian llvm::APSInt priority(32); 1379521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 1380521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 1381521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1382521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << "init_priority" << priorityExpr->getSourceRange(); 1383521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1384521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1385521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 13869f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned prioritynum = priority.getZExtValue(); 1387521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (prioritynum < 101 || prioritynum > 65535) { 1388521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 1389521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << priorityExpr->getSourceRange(); 1390521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1391521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1392521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1393521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian d->addAttr(::new (S.Context) InitPriorityAttr(prioritynum)); 1394521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian} 1395521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 1396bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1397bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1398803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 13996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1400545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 1401fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 14023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 14036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1406545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 14073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 14086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1411620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1412fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 14135dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 14146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14173568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 14186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 14196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 142001eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Format = Attr.getParameterName()->getName(); 14216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 14232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 14242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 14252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 14262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 14272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 14283c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 14293c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner if (Kind == IgnoredFormat) 14303c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return; 14313c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 14322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 1433fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 143401eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 14356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 1439545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1440803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 1441ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1442ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1443fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 14443c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 14456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14484fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson // FIXME: We should handle the implicit 'this' parameter in a more generic 14494fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson // way that can be used for other arguments. 14504fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson bool HasImplicitThisParam = false; 14514fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 14524fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson if (MD->isInstance()) { 14534fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson HasImplicitThisParam = true; 14544fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson NumArgs++; 14554fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson } 14564fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson } 14571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1459fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 14603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 14616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 14656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 1466bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 14674a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 14684a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 14694a2614e94672c47395abcde60518776fbebec589Sebastian Redl S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 14704a2614e94672c47395abcde60518776fbebec589Sebastian Redl << "a string type" << IdxExpr->getSourceRange(); 14714a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 14724a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 14734a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 14744a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 14751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 14773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 14786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 1480085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 1481fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1482fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 1483085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 1484085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 14852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 1486390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 1487390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 1488803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 1489390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1490fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1491fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 14926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1493bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 14946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 14956217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1496390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1497fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1498fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 14996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 1503545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1504803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 1505ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 1506ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1507fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 15083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 15096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 15136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 15143568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 15156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 15166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 1517803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 15186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 15233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 15242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 15256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 1526fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1527fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 15286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 15316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 1532fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 15333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 15346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15373d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(), 15382b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FirstArg.getZExtValue())); 15396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 15406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15410b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 15420b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 15436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1544545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 15453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 15466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 15500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 1551bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 15520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 15530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 15540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 15550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = dyn_cast<RecordDecl>(d); 15560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 15570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 1558fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 15595dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 1 /*union*/; 15606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD->isDefinition()) { 1564bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 15650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 15660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 15670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 15680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 156917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 157017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 15710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 15720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 15730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 15740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1575bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 15760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 15770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 157890cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 1579bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 158090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor diag::warn_transparent_union_attribute_floating) 158190cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor << FirstType->isVectorType() << FirstType; 15820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 15830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1584bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 15850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 15860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 15870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 15880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 15890c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 15900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 15910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 15920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1593bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 15940c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 1595bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 15960c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 15970c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 15980c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 1599bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 16000c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 16010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 1602bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 1603bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 1604bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 16056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 160640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis RD->addAttr(::new (S.Context) TransparentUnionAttr()); 16076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 16086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16090b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 16106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1611545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 16123c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 16136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1615797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1616797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1617bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 16196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 16206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 1621797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 16226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16243d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString())); 16256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 16266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16274ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthstatic void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { 16286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1629545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 16303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 16316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1633bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 1634bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 1635bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 1636bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 16376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1638545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 16396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 16407549c5589ac0d2087e55f2bdd4854adef23f29fdDaniel Dunbar // (For now we just use 128 bits which is the maximum on X86). 16414ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth D->addAttr(::new (S.Context) AlignedAttr(128)); 16424ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return; 16434ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth } 16444ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 16454ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth S.AddAlignedAttr(Attr.getLoc(), D, static_cast<Expr *>(Attr.getArg(0))); 16464ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 16474ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 16484ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { 16494ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (E->isTypeDependent() || E->isValueDependent()) { 16504ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth // Save dependent expressions in the AST to be instantiated. 16514ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth D->addAttr(::new (Context) AlignedAttr(E)); 16526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1654bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 165549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 16564ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (!E->isIntegerConstantExpr(Alignment, Context)) { 16574ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_argument_not_int) 16584ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << "aligned" << E->getSourceRange(); 165949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 166049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 1661396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 16624ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 16634ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << E->getSourceRange(); 1664396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 1665396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 1666396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 16674ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth D->addAttr(::new (Context) AlignedAttr(Alignment.getZExtValue() * 8)); 16686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1669fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1670bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1671bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 1672fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 1673bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 1674bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1675bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 16760b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1677fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 1678fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 1679fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1680fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 1681fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 16823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1683fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1684fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1685fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1686fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 1687fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 16880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1689fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1690fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1691210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 169201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Str = Attr.getParameterName()->getName(); 1693fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1694fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1695210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 1696210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 1697fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1698fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 1699fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 170073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 1701210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 1702fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 170373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 170473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 170573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 170673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 170773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 170873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 170973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 171073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 171173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 171273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 171373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 171473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 171573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 171673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 171773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 171873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1719fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1720fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 1721fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1722fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 1723210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 17240b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1725210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 17260b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 1727fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1728fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 1729210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 17300b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1731fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1732fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1733fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1734fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 1735fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1736fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 1737fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1738fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 1739fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 1740fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1741fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1742fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1743fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 174473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1745183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 174673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 174773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 17482ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!OldTy->isIntegralOrEnumerationType()) 174973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 175073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 175173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 175273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 175373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 175473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 175573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 175673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 175773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1758390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1759390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 1760390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1761390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 1762f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 1763f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 1764fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 1765fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 1766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 17673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 17703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1771fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1772fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 177373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 177473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 177573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 177673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1777fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 17780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 1779fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 17800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 1781fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1782fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 178373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 178473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 178573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 178673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1787fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 17880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 1789fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 17900b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 1791fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1792fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 1793fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 17940b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 1795fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 17960b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 1797fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 17980b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 1799fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1800fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 1801fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 18020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 1803fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 1804aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 1805aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 1806aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 1807aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 1808fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 1809aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 1810aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 1811aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 1812aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 1813fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 181473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 181573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 181673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1817f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 1818f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 1819f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1820f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 1821f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 1822f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 1823f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 1824f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 1825f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 182673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1827fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1828fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 182973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 183073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 1831fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1832fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1833fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 1834ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1835ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 1836a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 1837ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 1838fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 1839fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 18400744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 18411feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1842d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 1843d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson if (Attr.getNumArgs() > 0) { 1844d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1845d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1846d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1847e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 18485bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (!isFunctionOrMethod(d)) { 1849d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 18505dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1851d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1852d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1853bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18541feade8e520be483293dbf55eb57a51720899589Mike Stump d->addAttr(::new (S.Context) NoDebugAttr()); 1855d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 1856d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 18571feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 18585bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 18595bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (Attr.getNumArgs() != 0) { 18605bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 18615bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 18625bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1864c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 18655bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 18665dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 18675bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 18685bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1869bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18701feade8e520be483293dbf55eb57a51720899589Mike Stump d->addAttr(::new (S.Context) NoInlineAttr()); 18715bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 18725bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 18737255a2d997b15beae82e627052fdb1b2474495c2Chris Lattnerstatic void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr, 18747255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner Sema &S) { 18757255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner // check the attribute arguments. 18767255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner if (Attr.getNumArgs() != 0) { 18777255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 18787255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 18797255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 18807255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 18817255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner if (!isa<FunctionDecl>(d)) { 18827255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 18837255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner << Attr.getName() << 0 /*function*/; 18847255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 18857255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 18867255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 18877255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner d->addAttr(::new (S.Context) NoInstrumentFunctionAttr()); 18887255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner} 18897255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 1890cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 189126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 189226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner if (Attr.getNumArgs() != 0) { 189326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 189426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 189526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 1896bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1897c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1898c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 189926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 19005dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 190126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 190226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 1903bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 19040130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 1905cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1906c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 1907c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 1908bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 190940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) GNUInlineAttr()); 191026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 191126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 1912e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnarastatic void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1913e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // Diagnostic is emitted elsewhere: here we store the (valid) Attr 1914e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // in the Decl node for syntactic reasoning, e.g., pretty-printing. 1915e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara assert(Attr.isInvalid() == false); 1916e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 1917e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara switch (Attr.getKind()) { 1918e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_fastcall: 1919e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara d->addAttr(::new (S.Context) FastCallAttr()); 1920e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 1921e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_stdcall: 1922e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara d->addAttr(::new (S.Context) StdCallAttr()); 1923e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 1924f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 1925f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor d->addAttr(::new (S.Context) ThisCallAttr()); 1926e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_cdecl: 1927e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara d->addAttr(::new (S.Context) CDeclAttr()); 1928e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 1929e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara default: 1930e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara llvm_unreachable("unexpected attribute kind"); 1931e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 1932e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara } 1933e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara} 1934e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 1935ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1936ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian // check the attribute arguments. 1937ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (Attr.getNumArgs() != 1) { 193855d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1939ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1940ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 194155d3aaf9a537888734762170823daf750ea9036dEli Friedman 1942ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (!isFunctionOrMethod(d)) { 1943ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 19445dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1945ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1946ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 194755d3aaf9a537888734762170823daf750ea9036dEli Friedman 194855d3aaf9a537888734762170823daf750ea9036dEli Friedman Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 194955d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 1950ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 1951ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 195255d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 195355d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 195455d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 195555d3aaf9a537888734762170823daf750ea9036dEli Friedman } 195655d3aaf9a537888734762170823daf750ea9036dEli Friedman 1957264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov if (S.Context.Target.getRegParmMax() == 0) { 1958264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 195955d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 196055d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 196155d3aaf9a537888734762170823daf750ea9036dEli Friedman } 196255d3aaf9a537888734762170823daf750ea9036dEli Friedman 1963348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1964264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1965264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 196655d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 196755d3aaf9a537888734762170823daf750ea9036dEli Friedman } 196855d3aaf9a537888734762170823daf750ea9036dEli Friedman 196940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1970ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 1971ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 1972bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1973bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // check the attribute arguments. 1974bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Attr.getNumArgs() != 0) { 1975bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1976bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 1977bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 1978bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 1979bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!isa<CXXRecordDecl>(d) 1980bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 1981bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), 1982bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1983bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt : diag::warn_attribute_wrong_decl_type) 1984bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt << Attr.getName() << 7 /*virtual method or class*/; 1985bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 1986bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 19877725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 19887725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 19897725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 19907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<FinalAttr>()) { 19917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 19927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 19937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 1994bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 1995bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt d->addAttr(::new (S.Context) FinalAttr()); 1996bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 1997bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 19980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 19997725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt// C++0x member checking attributes 20007725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===// 20017725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 20037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 20047725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 20057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20067725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20077725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<CXXRecordDecl>(d)) { 20097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 20107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 20117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 20127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 9 /*class*/; 20137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<BaseCheckAttr>()) { 20177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 20187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt d->addAttr(::new (S.Context) BaseCheckAttr()); 20227725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 20237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 20257725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 20267725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 20277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20287725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20297725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20307725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<RecordDecl>(d->getDeclContext())) { 20317725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: It's not the type that's the problem 20327725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 20337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 20347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 20357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 11 /*member*/; 20367725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20377725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20387725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20397725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 20407725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20417725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<HidingAttr>()) { 20427725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 20437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt d->addAttr(::new (S.Context) HidingAttr()); 20477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 20487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20497725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 20507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 20517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 20527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20557725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 20567725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: It's not the type that's the problem 20577725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 20587725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 20597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 20607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 10 /*virtual method*/; 20617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 20657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<OverrideAttr>()) { 20677725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 20687725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20697725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20707725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt d->addAttr(::new (S.Context) OverrideAttr()); 20727725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 20737725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20747725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===// 2075b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 2076b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 2077b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2078b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 2079b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek Sema &S) { 2080b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 20815dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek QualType RetTy; 2082bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 20835dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 20845dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = MD->getResultType(); 20855dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 20865dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = FD->getResultType(); 20875dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 208821531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek SourceLocation L = Attr.getLoc(); 208921531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 209021531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 2091b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2092b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 2093bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 20946217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 2095183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall || RetTy->getAs<ObjCObjectPointerType>())) { 209621531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek SourceLocation L = Attr.getLoc(); 209721531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 209821531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek << SourceRange(L, L) << Attr.getName(); 2099bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 21005dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 2101bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2102b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek switch (Attr.getKind()) { 2103b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 2104b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek assert(0 && "invalid ownership attribute"); 2105b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 210631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 210731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr()); 210831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 210931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 211031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr()); 211131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 2112b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 211340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 2114b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2115b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 211640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 2117b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2118b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 2119b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 2120b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2121f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) { 2122f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return Attr.getKind() == AttributeList::AT_dllimport || 2123f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis Attr.getKind() == AttributeList::AT_dllexport; 2124f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 2125f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 2126b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 21270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 21280744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 21290744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 2130a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 2131803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 2132bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 2133bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 2134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D, 2135bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const AttributeList &Attr, Sema &S) { 2136e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara if (Attr.isInvalid()) 2137e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2138e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 2139f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 2140f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // FIXME: Try to deal with other __declspec attributes! 2141290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman return; 2142803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 214363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 2144857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 2145857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutletCollection: 2146857e918a8a40deb128840308a318bf623d68295fTed Kremenek HandleIBOutletCollection(D, Attr, S); break; 2147803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 2148ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 21496e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson case AttributeList::AT_vector_size: 2150bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 2151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 2152803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 21537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 21547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 2155bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 2156af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar HandleAlwaysInlineAttr (D, Attr, S); break; 2157b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 2158bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump HandleAnalyzerNoReturnAttr (D, Attr, S); break; 21597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 21607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 2161bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case AttributeList::AT_carries_dependency: 21627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt HandleDependencyAttr (D, Attr, S); break; 21637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 21647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 21657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 21663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 21679cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor HandleExtVectorTypeAttr(scope, D, Attr, S); 21683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 21697725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 21707725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 21717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 21727725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 21737725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 21747725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 21757725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 21767725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 2177dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_returns: 2178dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_takes: 2179dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_holds: 2180dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek HandleOwnershipAttr (D, Attr, S); break; 21817725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 21827725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 21837725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 2184b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2185b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 218631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 218731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 2188b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 2189b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 2190b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek HandleNSReturnsRetainedAttr(D, Attr, S); break; 2191b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 21926f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman case AttributeList::AT_reqd_wg_size: 21936f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman HandleReqdWorkGroupSize(D, Attr, S); break; 21946f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 2195521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian case AttributeList::AT_init_priority: 2196521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian HandleInitPriorityAttr(D, Attr, S); break; 2197521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 21987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 21997725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 22007725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 22017725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 22027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 22037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 2204026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 2205026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 22067725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 220711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 22087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 2209803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 2210803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 2211803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 22120db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 22130db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner HandleObjCExceptionAttr(D, Attr, S); 22140db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 2215f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 22167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 22177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 22187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 22197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 22207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 22217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 22227725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 22237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 22247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 2225bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 222605f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 222705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 22287255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 22297255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner HandleNoInstrumentFunctionAttr(D, Attr, S); 22307255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner break; 223104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_stdcall: 223204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_cdecl: 223304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_fastcall: 2234f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 2235e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara HandleCallConvAttr(D, Attr, S); 223604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 2237803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 223882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 223982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 224082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 22417d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 22427d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth << Attr.getName(); 2243803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 2244803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 2245803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 2246803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 2247803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 2248803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 22499cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 225011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola for (const AttributeList* l = AttrList; l; l = l->getNext()) { 225111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola ProcessDeclAttribute(S, D, *l, *this); 225211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 225311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 225411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC accepts 225511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a9 __attribute__((weakref)); 225611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // but that looks really pointless. We reject it. 225711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 225811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 2259dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(D)->getNameAsString(); 226011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 2261803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 2262803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 2263803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 2264e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 2265e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 22661eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 22677b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 2268e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 2269e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 2270e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 2271e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn FD->getLocation(), DeclarationName(II), 2272a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall FD->getType(), FD->getTypeSourceInfo()); 2273b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (FD->getQualifier()) { 2274b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 2275b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 2276b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 2277e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 2278e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 2279e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn VD->getLocation(), II, 2280a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 228116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClass(), 228216573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClassAsWritten()); 2283b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (VD->getQualifier()) { 2284b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall VarDecl *NewVD = cast<VarDecl>(NewD); 2285b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 2286b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 2287e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2288e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 2289e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 2290e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 2291e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 2292e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 22937b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 2294c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 2295c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 2296c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 2297c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 2298c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 22993d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName())); 2300c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner NewD->addAttr(::new (Context) WeakAttr()); 2301c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 2302c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 2303c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 2304c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 2305c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 2306c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 2307c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 2308c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 2309c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner ND->addAttr(::new (Context) WeakAttr()); 2310e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2311e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 2312e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 23130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 23140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 23150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 23169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 2317e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn // Handle #pragma weak 2318e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 2319e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (ND->hasLinkage()) { 2320e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 2321e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (W != WeakInfo()) { 23227b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn // Identifier referenced by #pragma weak before it was declared 23237b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn DeclApplyPragmaWeak(S, ND, W); 2324e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 2325e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2326e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2327e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2328e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 23290744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 23300744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 23319cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 2332bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23330744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 23340744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 23350744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 23360744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 23370744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 23380744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 23399cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 2340bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23410744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 23420744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 23439cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 23440744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 234554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 234654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// PushParsingDeclaration - Enter a new "scope" of deprecation 234754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// warnings. 234854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// 234954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// The state token we use is the start index of this scope 235054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// on the warning stack. 235154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallAction::ParsingDeclStackState Sema::PushParsingDeclaration() { 235254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclDepth++; 23532f514480c448708ec382a684cf5e035d3a827ec8John McCall return (ParsingDeclStackState) DelayedDiagnostics.size(); 235454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 235554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 235654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallvoid Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) { 235754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 235854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclDepth--; 235954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 23602f514480c448708ec382a684cf5e035d3a827ec8John McCall if (DelayedDiagnostics.empty()) 236154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 236254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 236354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall unsigned SavedIndex = (unsigned) S; 23642f514480c448708ec382a684cf5e035d3a827ec8John McCall assert(SavedIndex <= DelayedDiagnostics.size() && 236554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall "saved index is out of bounds"); 236654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 236758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall unsigned E = DelayedDiagnostics.size(); 236858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 23692f514480c448708ec382a684cf5e035d3a827ec8John McCall // We only want to actually emit delayed diagnostics when we 23702f514480c448708ec382a684cf5e035d3a827ec8John McCall // successfully parsed a decl. 23712f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *D = Ctx ? Ctx.getAs<Decl>() : 0; 23722f514480c448708ec382a684cf5e035d3a827ec8John McCall if (D) { 23732f514480c448708ec382a684cf5e035d3a827ec8John McCall // We really do want to start with 0 here. We get one push for a 23742f514480c448708ec382a684cf5e035d3a827ec8John McCall // decl spec and another for each declarator; in a decl group like: 23752f514480c448708ec382a684cf5e035d3a827ec8John McCall // deprecated_typedef foo, *bar, baz(); 23762f514480c448708ec382a684cf5e035d3a827ec8John McCall // only the declarator pops will be passed decls. This is correct; 23772f514480c448708ec382a684cf5e035d3a827ec8John McCall // we really do need to consider delayed diagnostics from the decl spec 23782f514480c448708ec382a684cf5e035d3a827ec8John McCall // for each of the different declarations. 237958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall for (unsigned I = 0; I != E; ++I) { 23802f514480c448708ec382a684cf5e035d3a827ec8John McCall if (DelayedDiagnostics[I].Triggered) 23812f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 23822f514480c448708ec382a684cf5e035d3a827ec8John McCall 23832f514480c448708ec382a684cf5e035d3a827ec8John McCall switch (DelayedDiagnostics[I].Kind) { 23842f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 23852f514480c448708ec382a684cf5e035d3a827ec8John McCall HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 23862f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 23872f514480c448708ec382a684cf5e035d3a827ec8John McCall 23882f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 23892f514480c448708ec382a684cf5e035d3a827ec8John McCall HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 23902f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 239154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 239254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 239354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 239454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 239558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall // Destroy all the delayed diagnostics we're about to pop off. 239658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall for (unsigned I = SavedIndex; I != E; ++I) 239758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall DelayedDiagnostics[I].destroy(); 239858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 23992f514480c448708ec382a684cf5e035d3a827ec8John McCall DelayedDiagnostics.set_size(SavedIndex); 24002f514480c448708ec382a684cf5e035d3a827ec8John McCall} 24012f514480c448708ec382a684cf5e035d3a827ec8John McCall 24022f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 24032f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 24042f514480c448708ec382a684cf5e035d3a827ec8John McCall if (D->hasAttr<DeprecatedAttr>()) 24052f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 24062f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 24072f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 24082f514480c448708ec382a684cf5e035d3a827ec8John McCall} 24092f514480c448708ec382a684cf5e035d3a827ec8John McCall 24102f514480c448708ec382a684cf5e035d3a827ec8John McCallvoid Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD, 24112f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 24122f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 24132f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 24142f514480c448708ec382a684cf5e035d3a827ec8John McCall 24152f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 24162f514480c448708ec382a684cf5e035d3a827ec8John McCall Diag(DD.Loc, diag::warn_deprecated) 24172f514480c448708ec382a684cf5e035d3a827ec8John McCall << DD.DeprecationData.Decl->getDeclName(); 241854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 241954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 242054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallvoid Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) { 242154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 242254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (ParsingDeclDepth) { 24232f514480c448708ec382a684cf5e035d3a827ec8John McCall DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D)); 242454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 242554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 242654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 242754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 242854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (isDeclDeprecated(cast<Decl>(CurContext))) 242954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 243054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 243154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 243254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 2433